基于母列表生成子列表的Java代码实现问题
按File_identifier分组并以Typeflux为Key存入HashMap时的重复问题解决
你遇到的问题是原代码的双重循环逻辑存在缺陷,导致生成的子列表出现重复,而且无法正确处理多对象分组的场景。先来看下原代码的问题,再给出修正方案。
原代码问题分析
HashMap<String, List<SentinelReportModel>> hashmap = new HashMap<String, List<SentinelReportModel>>(); for (int i = 0; i < sentinelReportModels.size(); i++) { for (int k = 0; k < sentinelReportModels.size(); k++) { if (sentinelReportModels.get(i).getIdentifiantfichier() .equals(sentinelReportModels.get(k).getIdentifiantfichier()) ) { ArrayList<SentinelReportModel> listeTemp = new ArrayList<>(); listeTemp.add(sentinelReportModels.get(i)); listeTemp.add(sentinelReportModels.get(k)); hashmap.put(sentinelReportModels.get(i).getTypeflux(),listeTemp); } } }
这段代码的核心问题:
- 重复处理与重复添加:双重循环会遍历所有对象对,比如
i=0,k=1和i=1,k=0都会触发条件,生成两个几乎相同的列表并重复存入HashMap,导致Key被频繁覆盖,列表内容重复。 - 无法处理多对象分组:如果同一个
Identifiantfichier下有3个或更多对象,原代码只会每次添加两个对象,生成多个不完整的分组列表。 - 无复用列表:每次匹配都新建
ArrayList,没有复用已存在的分组列表,既浪费内存又导致数据混乱。
修正方案
方案一:使用Java 8+ Stream API(简洁高效)
先按Identifiantfichier完成分组,再将分组后的列表按Typeflux聚合(支持两种模式,按需选择):
// 第一步:按文件标识分组,得到每个Identifiantfichier对应的所有模型 Map<String, List<SentinelReportModel>> fileIdGroups = sentinelReportModels.stream() .collect(Collectors.groupingBy(SentinelReportModel::getIdentifiantfichier)); // 第二步:转换为以Typeflux为Key的HashMap HashMap<String, List<SentinelReportModel>> resultMap = new HashMap<>(); fileIdGroups.values().forEach(group -> { if (group.isEmpty()) return; String typeFluxKey = group.get(0).getTypeflux(); // 模式1:同一Typeflux下合并所有同类型的文件分组(推荐,避免覆盖) resultMap.computeIfAbsent(typeFluxKey, key -> new ArrayList<>()).addAll(group); // 模式2:每个文件分组单独存入,若Typeflux相同则覆盖(按需使用) // resultMap.put(typeFluxKey, group); });
方案二:使用普通循环(兼容低版本Java)
逻辑和Stream方案一致,用传统循环实现:
// 第一步:按Identifiantfichier分组 HashMap<String, List<SentinelReportModel>> fileIdGroups = new HashMap<>(); for (SentinelReportModel model : sentinelReportModels) { String fileId = model.getIdentifiantfichier(); // 不存在则新建列表,存在则直接添加 fileIdGroups.computeIfAbsent(fileId, key -> new ArrayList<>()).add(model); } // 第二步:转换为以Typeflux为Key的HashMap HashMap<String, List<SentinelReportModel>> resultMap = new HashMap<>(); for (List<SentinelReportModel> group : fileIdGroups.values()) { if (group.isEmpty()) continue; String typeFluxKey = group.get(0).getTypeflux(); // 模式1:合并同Typeflux的所有分组 resultMap.computeIfAbsent(typeFluxKey, key -> new ArrayList<>()).addAll(group); // 模式2:覆盖式存入 // resultMap.put(typeFluxKey, group); }
关键说明
- 假设同一
Identifiantfichier下的所有对象Typeflux属性值相同,如果存在同一文件标识下Typeflux不同的情况,你需要额外处理(比如取第一个对象的Typeflux,或者按Typeflux再细分)。 computeIfAbsent方法会自动判断Key是否存在,不存在则执行Lambda表达式新建列表,避免了手动判空的繁琐。
内容的提问来源于stack exchange,提问作者Fosfor
相关产品推荐
相关产品推荐

