3 回答

TA贡献1966条经验 获得超4个赞
不,过滤器不会扫描整个流。这是一个中间操作,它返回一个惰性流(实际上所有中间操作都返回一个惰性流)。为了说服您,您可以简单地进行以下测试:
List<Integer> list = Arrays.asList(1, 10, 3, 7, 5);
int a = list.stream()
.peek(num -> System.out.println("will filter " + num))
.filter(x -> x > 5)
.findFirst()
.get();
System.out.println(a);
哪个输出:
will filter 1
will filter 10
10
您会看到实际上仅处理了流的前两个元素。
因此,您可以采用完全正确的方法。

TA贡献2065条经验 获得超14个赞
但是这对我来说似乎效率低下,因为过滤器将扫描整个列表
不,它不会-一旦找到满足谓词的第一个元素,它就会“中断”。您可以在流包javadoc中阅读有关懒惰的更多信息,尤其是(强调我的):
许多流操作(例如过滤,映射或重复删除)可以延迟实施,从而暴露出进行优化的机会。例如,“使用三个连续的元音查找第一个字符串”不需要检查所有输入字符串。流操作分为中间(流产生)操作和终端(产生值或副作用)操作。中间操作总是很懒。

TA贡献1775条经验 获得超8个赞
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
// Stream is ~30 times slower for same operation...
public class StreamPerfTest {
int iterations = 100;
List<Integer> list = Arrays.asList(1, 10, 3, 7, 5);
// 55 ms
@Test
public void stream() {
for (int i = 0; i < iterations; i++) {
Optional<Integer> result = list.stream()
.filter(x -> x > 5)
.findFirst();
System.out.println(result.orElse(null));
}
}
// 2 ms
@Test
public void loop() {
for (int i = 0; i < iterations; i++) {
Integer result = null;
for (Integer walk : list) {
if (walk > 5) {
result = walk;
break;
}
}
System.out.println(result);
}
}
}
添加回答
举报