Java 8 Stream处理大列表时的filter操作是否比普通for循环更耗时?
Java Stream多filter操作性能问题解答
你对Stream的运行机制存在认知偏差,这段Stream实现的时间复杂度和原有for循环完全一致,并不会更高。
核心原理说明
- Java Stream的操作分为中间操作和终止操作两类,filter属于中间操作,这类操作都是惰性执行的,只有调用了findFirst()这类终止操作时,才会真正开始遍历数据做计算。
- 多个连续的filter不会触发多次列表遍历:Stream会把所有中间操作拼接成一条处理链,每个元素只会按顺序经过一次处理链上的所有判断,只要某一步不满足条件就会直接跳过该元素的后续判断,不会重复遍历列表。
- findFirst()属于短路终止操作,和你原有for循环里的break逻辑完全一致:一旦找到第一个符合所有filter条件的元素,就会立刻终止整个遍历流程,不会再处理后续元素。
实际执行流程对比
你给出的代码实际运行时的遍历次数和原有for循环完全相同,都是6次:
- 依次遍历1、2、3、4,均不满足
e>4的条件,直接跳过 - 遍历到5,满足
e>4但不满足e%2==0,跳过 - 遍历到6,同时满足两个filter条件,直接返回该元素终止流程
优化建议
你也可以把两个filter的条件合并成一个,写法更简洁,执行效果没有任何区别:
numbers.stream() .filter(e -> e > 4 && e % 2 == 0) .findFirst()
原有for循环的问题说明
另外你原来的for循环存在逻辑错误:增强for循环里的变量i已经是列表中的元素值而非下标,直接打印i即可,调用numbers.get(i)会取下标为i的元素,当匹配到i=6时实际会输出列表下标6对应的元素7,和你预期的输出结果不符。
内容的提问来源于stack exchange,提问作者Ashish
相关产品推荐
相关产品推荐

