在 Java 里,Stream 的filter
和 List 的removeIf
筛选效率要依据具体情形来判断。
1. 操作本质有别
- Stream 的 filter:
- 它是一种中间操作,不会立刻执行,而是把筛选条件记录下来。只有遇到终端操作时,才会开始处理元素。
- 此操作不会对原集合进行修改,而是生成一个新的流。
- List 的 removeIf:
- 这是一种终端操作,会立即对原集合进行修改,删除满足条件的元素。
- 它直接在原集合上进行元素的删除操作。
2. 效率对比分情况
- 单次筛选场景:
当你只需要对集合进行一次筛选时,removeIf
的效率更高。这是因为它直接在原集合上进行操作,避免了创建新的流和中间集合。 - 链式操作场景:
如果需要进行多次筛选或者其他中间操作,Stream 的filter
会更高效。因为 Stream 采用延迟执行策略,能将多个操作进行优化合并,减少遍历次数。
3. 示例与性能测试
下面通过代码来直观感受两者的性能差异:
java
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;public class FilterVsRemoveIf {public static void main(String[] args) {// 创建一个包含大量元素的列表List<Integer> list = new ArrayList<>();for (int i = 0; i < 1000000; i++) {list.add(i);}// 测试Stream的filterlong startTime = System.currentTimeMillis();List<Integer> filteredList = list.stream().filter(e -> e % 2 == 0).collect(Collectors.toList());long endTime = System.currentTimeMillis();System.out.println("Stream filter耗时: " + (endTime - startTime) + "ms");// 重新创建相同的列表用于测试removeIflist = new ArrayList<>();for (int i = 0; i < 1000000; i++) {list.add(i);}// 测试List的removeIfstartTime = System.currentTimeMillis();list.removeIf(e -> e % 2 != 0);endTime = System.currentTimeMillis();System.out.println("List removeIf耗时: " + (endTime - startTime) + "ms");}
}
测试结果分析:
- Stream 的 filter:由于要创建流、中间集合以及进行终端操作,会带来一些额外的开销。
- List 的 removeIf:直接在原集合上进行操作,无需创建新的集合,所以速度更快。
4. 如何选择
- 选择 Stream 的 filter 的情况:
- 你不想对原集合进行修改。
- 需要进行链式操作,比如多次筛选、映射等。
- 希望代码更加简洁易读。
- 选择 List 的 removeIf 的情况:
- 你想直接修改原集合。
- 只需要进行一次筛选操作。
- 追求更高的性能。
综上所述,在单次筛选且需要修改原集合时,removeIf
是更好的选择;而在需要链式操作或者保留原集合的场景下,filter
更为合适。结合本人使用心得,当你使用当前处理器与其他处理器公用一个传入变量时,使用流式处理,不要操作原对象;仅有当前处理器时,建议使用list自有方法,因为它速度更快。