如何用Java Stream API分区流数据,实现ID分流与对象映射?
问题描述
现有ID列表myIdList,以及关联ID与对象的Map<String, Object>类型集合myObjectMap。需求如下:
- 遍历ID列表,若ID存在于
myObjectMap中,将对应对象加入新的对象列表 - 若ID不存在,将其加入缺失ID列表
目前已通过for-each循环实现该逻辑:
List<String> myIdList = Arrays.asList("a", "b", "c"); Map<String,Object> myObjectMap = new HashMap<>(); List<Object> objectList = new ArrayList<>(); List<String> missingObjIds = new ArrayList<>(); for(String id : myIdList) { Object obj = myObjectMap.get(id); if(obj == null) { missingObjIds.add(id); } else { objectList.add(obj); } }
希望用更简洁的Stream API实现,但尝试分区流后未得到理想结果,寻求可行方案。
解决方案
可以通过Collectors.partitioningBy先对ID进行分区,再分别提取缺失ID和对应对象列表,实现纯Stream风格的操作:
List<String> myIdList = Arrays.asList("a", "b", "c"); Map<String, Object> myObjectMap = new HashMap<>(); // 示例:给map添加部分数据 myObjectMap.put("a", new Object()); // 1. 按ID是否存在于map中分区 Map<Boolean, List<String>> idPartition = myIdList.stream() .collect(Collectors.partitioningBy(myObjectMap::containsKey)); // 2. 提取缺失的ID列表 List<String> missingObjIds = idPartition.get(false); // 3. 提取存在ID对应的对象列表 List<Object> objectList = idPartition.get(true).stream() .map(myObjectMap::get) .collect(Collectors.toList());
逻辑说明
Collectors.partitioningBy(myObjectMap::containsKey)会将ID列表分成两组:key为true的是存在于map中的ID,false的是缺失的ID- 后续分别从分区结果中提取两个列表,其中存在的ID通过
map(myObjectMap::get)直接映射为对应对象
如果想要一步完成收集,也可以自定义一个容器类,通过Collector.of实现一次性收集,但代码复杂度会略高,上面的分区方式更简洁易读,符合Stream的声明式编程风格。
内容的提问来源于stack exchange,提问作者chama
相关产品推荐
相关产品推荐

