Java使用groupingBy分组时如何过滤不符合条件的整个分组
正确实现方案
方案1:先完整分组再过滤分组(逻辑最清晰,适合绝大多数场景)
Map<String, List<MyObject>> output = myObjectList.stream() // 先按ID完整分组,保留每个ID下的所有原始元素 .collect(Collectors.groupingBy(MyObject::getId)) .entrySet() .stream() // 仅保留分组内存在Description为"keep this group"的分组 .filter(entry -> entry.getValue().stream() .anyMatch(obj -> "keep this group".equals(obj.getDescription()))) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
该方案最终会完全剔除ID为2的分组,ID为1的分组会保留全部3个原始元素,完全符合需求。
方案2:先筛选保留ID再分组(适合数据量极大的场景,减少内存占用)
// 先提取所有包含目标描述的ID,存入集合 Set<String> keptIdSet = myObjectList.stream() .filter(obj -> "keep this group".equals(obj.getDescription())) .map(MyObject::getId) .collect(Collectors.toSet()); // 过滤原列表中属于保留ID的元素后再分组 Map<String, List<MyObject>> output = myObjectList.stream() .filter(obj -> keptIdSet.contains(obj.getId())) .collect(Collectors.groupingBy(MyObject::getId));
原代码问题说明
你原来使用的Collectors.filtering是分组后对组内元素做过滤,不会删除分组本身,无论过滤后组内是否有元素,对应的ID键都会保留,所以才会出现ID为2对应空列表的结果。
内容的提问来源于stack exchange,提问作者navig8tr
相关产品推荐
相关产品推荐

