我有一个简单的流程,如下所示:
List<Long> r = l.stream()
.filter(a->a.getB() % 2 == 0)
.map(A::getB)
.collect(Collectors.toList());但Intellij建议我:
可以交换
'filter()‘和'map()’检查信息:可以简化的Reports流API调用链。它允许在遍历集合时避免创建冗余的临时对象。例如:
Intellij给出的例子很容易理解,但我不明白为什么它建议我使用map().filter()。
我查看了ReferencePipeline的来源,但没有发现任何线索:当涉及到与流实现相关的临时对象时,map().filter()或filter().map()没有什么区别(如果A.b是一个原语,则filter().map()将有较少的自动装箱功能,这使我更加困惑)。
那么,我是遗漏了流实现的某个点,还是这是Intellij的错误警报?
发布于 2021-04-07 04:57:11
a.getB()被调用两次--一次在过滤器内,它也是映射函数,因此,与其执行两次调用,不如首先使用getB映射它,然后过滤掉它。
List<Long> r = l.stream().map(A::getB).filter(b->b % 2 == 0).collect(Collectors.toList());
编辑
如果getB返回一个long,那么可以使用mapToLong来避免中间装箱操作。
List<Long> r = l.stream()
.mapToLong(A::getB)
.filter(b->b % 2 == 0)
.boxed()
.collect(Collectors.toList());样本输出
使用静态计数器来计数get方法的调用:
class A {
public static int count = 0;
private long b;
public long getB() {
count++;
return b;
}
}List<A> list= List.of(new A(1L), new A(3L), new A(4L));list.stream()
.filter(a -> a.getB()%2 == 0)
.map(A::getB)
.collect(Collectors.toList());
System.out.println(A.count); // returns 4鉴于
list.stream()
.mapToLong(A::getB)
.filter(b->b % 2 == 0)
.boxed()
.collect(Collectors.toList());
System.out.println(A.count); // returns 3https://stackoverflow.com/questions/66979712
复制相似问题