Java两个Stream流处理API数据时调用对象方法及流合并方案
Java Stream 实现方案
基础实现(无需强制合并流)
你两个流的数据源、最终调用的目标方法均不相同,强行合并反而会降低代码可读性,首先补全你原思路的正确实现,分两种常用场景:
场景1:对map后的每个元素逐个调用目标方法
SimpleObject obj = new SimpleObject(); // stream1 处理逻辑 StreamSupport.stream(myApi.getData()) .map(myfunctions::function) .forEach(obj::specificFunction1); // 终端操作触发执行,每个映射后的元素会作为参数传入specificFunction1 // stream2 处理逻辑 StreamSupport.stream(myApi.getOtherData()) .map(myfunctions::function) .forEach(obj::specificFunction2); // 每个映射后的元素作为参数传入specificFunction2
场景2:收集所有map后的结果为集合,一次性调用目标方法
SimpleObject obj = new SimpleObject(); // stream1 处理逻辑 List<映射后的数据类型> result1 = StreamSupport.stream(myApi.getData()) .map(myfunctions::function) .toList(); obj.specificFunction1(result1); // stream2 处理逻辑 List<映射后的数据类型> result2 = StreamSupport.stream(myApi.getOtherData()) .map(myfunctions::function) .toList(); obj.specificFunction2(result2);
优化方案:抽离重复逻辑
两个流都包含「Iterable转Stream + 执行公共映射方法」的重复步骤,可以抽成公共工具方法简化代码:
// 抽离公共的流构建+映射逻辑 private <T, R> Stream<R> buildMappedStream(Iterable<T> source) { return StreamSupport.stream(source) .map(myfunctions::function); }
抽离后调用代码可以简化为:
SimpleObject obj = new SimpleObject(); // 场景1调用 buildMappedStream(myApi.getData()).forEach(obj::specificFunction1); buildMappedStream(myApi.getOtherData()).forEach(obj::specificFunction2); // 场景2调用 // obj.specificFunction1(buildMappedStream(myApi.getData()).toList()); // obj.specificFunction2(buildMappedStream(myApi.getOtherData()).toList());
特殊场景的合并方案
如果你有统一管理流处理生命周期的特殊需求,可以用以下方式合并逻辑,但可读性比分开实现差,不推荐常规场景使用:
SimpleObject obj = new SimpleObject(); Stream.of( Map.entry(myApi.getData(), (Consumer<映射后的数据类型>) obj::specificFunction1), Map.entry(myApi.getOtherData(), (Consumer<映射后的数据类型>) obj::specificFunction2) ).forEach(entry -> buildMappedStream(entry.getKey()).forEach(entry.getValue()));
注意事项
Java Stream是惰性求值的,只有遇到终端操作(forEach、collect、toList等)时,中间的map、peek等操作才会实际执行,你原来的写法缺少终端操作,对应的方法调用永远不会触发。
内容的提问来源于stack exchange,提问作者Zed
相关产品推荐
相关产品推荐

