是否可以使用java8进一步优化以下代码?

时间:2018-08-31 03:27:33

标签: java optimization collections java-8 java-stream

我在项目中遇到以下代码。我想知道是否可以通过使用Java 8流或一般通过collection API进一步对其进行优化。

private Set<Student> getFilteredSet() {
    Set<Student> unfilteredSet = getAllStudents();
    Set<Student> adminAreaSet = getAdminStudents();

    Set<String> adminAreaID = new HashSet<>();
    Set<Student> filteredSet = new HashSet<>();

    for (final Student student : adminAreaSet) {
        adminAreaID.add(student.getId());
    }
    for (final Student student : unfilteredSet) {
        if (adminAreaID.contains(student.getId())) {
            filteredSet.add(student);
        }
    }   
    return filteredSet;
}

注意unfilteredSetadminAreaSet拥有Student

的不同子类型

2 个答案:

答案 0 :(得分:8)

由于问题是用标记的,因此提高代码可读性的一种方法是将其转换为:

Set<String> adminAreaID = getAdminStudents().stream()
        .map(Student::getId)
        .collect(Collectors.toSet());

return getAllStudents().stream()
        .filter(student -> adminAreaID.contains(student.getId()))
        .collect(Collectors.toSet());

答案 1 :(得分:2)

根据您的评论,您正在寻找速度优化。有很多文章比较Stream和Collection,甚至更多有关整个Internet的文章。 我以示例的方式建议您看一下这个问题,该问题针对每个循环比较Streams和Old之间的速度性能: Java 8: performance of Streams vs Collections。 使用Stream创建大量中间对象并调用中间方法时,每个循环的速度都比基本速度慢是正常的。 但是,您可以使用流来获得更具可读性/更小的代码。

要回答这个问题,考虑到速度性能,我认为您的代码已经很好。我所看到的是您应该初始化adminAreaID,因为您确切知道它将具有的大小:

    Set<String> adminAreaID = new HashSet<>(adminAreaSet.size(), 1.);

通过设置大小和负载因子,可以确保没有时间花在长大您的设备上。 根据{{​​3}}:

  

负载因子是衡量哈希表已满的程度的度量   在自动增加容量之前获得。

您必须将其设置为1,因为您不会获得更高的adminAreaSet大小。此外,如果将其设置为.75(默认值),则当循环达到其容量的75%(这是无用的)时,您的Set将增长一次。

如果没有内存问题,则应该对filteredSet进行相同的操作:

    Set<Student> filteredSet = new HashSet<>(unfilteredSet.size(), 1.);

实际上,当您过滤unfilteredSet时,您不会达到最大容量,但是它将确保您在filteredSet填充期间不会长大。