Ton*_*ony 6 java intellij-idea java-stream
我有一个简单的流,如下所示:
List<Long> r = l.stream()
.filter(a->a.getB() % 2 == 0)
.map(A::getB)
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
但 Intellij 建议我:
'filter()' 和 'map()' 可以交换检查信息:报告可以简化的流 API 调用链。它允许在遍历集合时避免创建冗余的临时对象。例如
- collection.stream().forEach() ?集合.forEach()
- collection.stream().collect(toList/toSet/toCollection()) ? 新的集合类型<>(集合)
Intellij 给出的例子很容易理解,但我不明白为什么它建议我map().filter().
我查看了来源ReferencePipeline但没有发现任何线索:map().filter()或者filter().map()在与流实现相关的临时对象方面没有区别(filter().map()如果A.b是一个让我更加困惑的原语,那么自动装箱会更少)。
那么,我是否缺少流实现的某些点,或者这是 Intellij 的误报?
a.getB()被调用两次 - 一次在过滤器内部,它也是映射函数,所以不要这样做两次,最好先使用映射getB然后过滤掉它
List<Long> r = l.stream().map(A::getB).filter(b->b % 2 == 0).collect(Collectors.toList());
编辑
如果getB返回 a longthenmapToLong可用于避免中间装箱操作。
List<Long> r = l.stream()
.mapToLong(A::getB)
.filter(b->b % 2 == 0)
.boxed()
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
样品输出
使用静态计数器计算 get 方法的调用:
class A {
public static int count = 0;
private long b;
public long getB() {
count++;
return b;
}
}
Run Code Online (Sandbox Code Playgroud)
List<A> list= List.of(new A(1L), new A(3L), new A(4L));
Run Code Online (Sandbox Code Playgroud)
list.stream()
.filter(a -> a.getB()%2 == 0)
.map(A::getB)
.collect(Collectors.toList());
System.out.println(A.count); // returns 4
Run Code Online (Sandbox Code Playgroud)
然而
list.stream()
.mapToLong(A::getB)
.filter(b->b % 2 == 0)
.boxed()
.collect(Collectors.toList());
System.out.println(A.count); // returns 3
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
440 次 |
| 最近记录: |