如何使用Java 8 Stream合并ProductInfo列表为单个对象
Java 8 Stream 优化多层级列表合并方案
我来帮你把这段嵌套循环的代码改成更简洁易读的Java 8 Stream实现,不仅能减少嵌套层级,还能通过Stream的链式调用让逻辑更清晰。
情况1:收集所有订单中所有ProductInfo的服务标签,合并为一个ProductInfo
如果你的需求是把所有OrderDetail里的所有ProductInfo的servicetagInfo全部收集起来,合并成一个ProductInfo对象,那么可以这样写:
import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Objects; import java.util.stream.Collectors; // 收集所有服务标签 List<String> serviceTagList = arInvoiceOrderResponseBody.getOrders().stream() // 过滤掉null的OrderDetail .filter(Objects::nonNull) // 提取每个OrderDetail的ProductInfo列表 .map(OrderDetail::getProductInfo) // 过滤掉null或空的ProductInfo列表 .filter(piList -> piList != null && !piList.isEmpty()) // 将多个ProductInfo列表扁平化为单个ProductInfo流 .flatMap(Collection::stream) // 过滤掉null的ProductInfo .filter(Objects::nonNull) // 提取每个ProductInfo的servicetagInfo列表 .map(ProductInfo::getServicetagInfo) // 过滤掉null的servicetagInfo列表 .filter(Objects::nonNull) // 将多个标签列表扁平化为单个字符串流 .flatMap(Collection::stream) // 收集为ArrayList .collect(Collectors.toCollection(ArrayList::new)); // 创建合并后的ProductInfo并设置到目标OrderDetail(注意:原代码中orderDetail是循环变量,需确保是你需要修改的那个订单) ProductInfo mergedProductInfo = new ProductInfo(); mergedProductInfo.setServicetagInfo(serviceTagList); orderDetail.setProductInfo(Arrays.asList(mergedProductInfo));
情况2:为每个OrderDetail单独合并自身的ProductInfo
如果你的真实需求是对每个OrderDetail,把它自己的多个ProductInfo合并成一个,整合所有服务标签(这更符合常规业务场景),那可以用forEach结合Stream来实现:
import java.util.Collections; import java.util.Collection; import java.util.Objects; import java.util.stream.Collectors; arInvoiceOrderResponseBody.getOrders().stream() // 过滤掉null的OrderDetail .filter(Objects::nonNull) // 对每个OrderDetail单独处理 .forEach(orderDetail -> { // 收集当前OrderDetail下所有ProductInfo的服务标签 List<String> tags = orderDetail.getProductInfo().stream() .filter(Objects::nonNull) .map(ProductInfo::getServicetagInfo) .filter(Objects::nonNull) .flatMap(Collection::stream) .collect(Collectors.toList()); // 创建合并后的ProductInfo ProductInfo mergedPi = new ProductInfo(); mergedPi.setServicetagInfo(tags); // 替换当前OrderDetail的productInfo列表 orderDetail.setProductInfo(Collections.singletonList(mergedPi)); });
代码细节说明
filter(Objects::nonNull):替代原代码中繁琐的null判断,确保只处理非空对象;flatMap(Collection::stream):把嵌套的列表结构扁平化,直接替代多层嵌套循环;Collectors.toCollection(ArrayList::new):如果需要指定具体的集合实现(比如ArrayList),可以用这个替代默认的toList();Collections.singletonList(mergedPi):如果不需要修改合并后的ProductInfo列表,用这个比Arrays.asList()更高效。
内容的提问来源于stack exchange,提问作者Sachin HR
相关产品推荐
相关产品推荐

