java集合stream和普通for
在代码中:
//数据量大, 不适用流操作,使用传统for循环操作
Map<String, List<ResultVo>> map = new HashMap<>();
for (ResultVo vo : VoList) {
String Id = vo.getid();
map.computeIfAbsent(id, k -> new ArrayList<>()).add(vo);
}
选择传统 for 循环而不是 Java Stream 的原因如下:
1. 性能优化
- Stream API 虽然代码更简洁,但其内部实现使用了较多的中间对象和函数式调用,相比传统
for循环会有额外的 性能开销。 - 当数据量较大时(如成千上万条告警数据),这种开销会变得明显。使用传统
for循环可以避免这些额外开销,提高执行效率。
2. 内存占用更低
- Stream 操作通常会创建中间集合或包装器对象(如
Collectors.groupingBy),在大数据量场景下会增加 内存消耗。 - 传统
for循环直接操作Map和List,结构更清晰、内存更可控。
3. 可读性与调试更友好
- 在复杂的逻辑处理中,传统的
for循环更容易 调试 和 跟踪执行流程。 - Stream 链式调用在某些情况下会降低代码可读性,尤其是在嵌套分组或条件判断时。
4. 避免潜在的并发问题
- 如果将来代码需要并行处理,Stream 的
parallel()机制可能会引入并发问题,而传统for循环则更易于控制并发逻辑。 - 当前场景中不需要并行处理,所以直接使用顺序循环更稳妥。
总结:
选择传统 for 循环是为了在 大数据量场景下提高性能、降低内存开销,并提升 可读性与调试便利性。这属于一种 基于实际性能考虑的编码优化策略。
测试代码
public static void main(String[] args) {
// 时间戳输出
List<List<ResIndexDetail>> list = new ArrayList<>();
for (int i = 0; i < 10000; i++){
List<ResIndexDetail> resIndexDetailList = new ArrayList<>();
for (int j = 0; j < 100; j++){
ResIndexDetail resIndexDetail = new ResIndexDetail();
resIndexDetail.setId(i + "");
resIndexDetailList.add(resIndexDetail);
}
list.add(resIndexDetailList);
}
System.out.println(System.currentTimeMillis());
// 使用stream流的方式实现
Map<String,Object> collect =list.stream().map(e->{
return e;
}).collect(Collectors.toMap(e->e.get(0).getId(),e->e));
System.out.println(System.currentTimeMillis());
// 使用for循环
Map<String,Object> collect1 =new HashMap<>();
for (int i = 0; i < list.size(); i++) {
List<ResIndexDetail> resIndexDetailList = list.get(i);
for (int j = 0; j < resIndexDetailList.size(); j++) {
ResIndexDetail resIndexDetail = resIndexDetailList.get(j);
collect1.put(resIndexDetail.getId(),resIndexDetail);
}
}
System.out.println(System.currentTimeMillis());
}
浙公网安备 33010602011771号