如何遍历ArrayList生成Person无序对(2组合),比较HashMap值差?
嘿,这个需求我刚好之前处理过类似的场景,给你一步步拆解怎么实现:
核心思路:避免重复比较的遍历方式
要避免A和C、C和A这种重复比较,最直接高效的方式就是用双层循环+索引错位:外层循环从第1个元素遍历到倒数第2个,内层循环从外层当前索引的下一个元素开始遍历到最后一个。这样每一对Person只会被比较一次,完全不会重复。
具体代码实现
首先先明确下Person类的结构(方便你对照):
class Person { // 假设每个Person持有多个HashMap,用List存储 private List<HashMap<String, Integer>> dataMaps; // 构造器、getter方法 public Person(List<HashMap<String, Integer>> dataMaps) { this.dataMaps = dataMaps; } public List<HashMap<String, Integer>> getDataMaps() { return dataMaps; } }
接下来是核心的遍历和比较逻辑:
import java.util.ArrayList; import java.util.HashMap; import java.util.Map; public class PersonComparer { public static void main(String[] args) { // 模拟你的Person集合 ArrayList<Person> personList = new ArrayList<>(); // 这里可以添加测试用的Person实例,比如: HashMap<String, Integer> map1 = new HashMap<>(); map1.put("score", 85); map1.put("age", 25); personList.add(new Person(new ArrayList<>(){{add(map1);}})); HashMap<String, Integer> map2 = new HashMap<>(); map2.put("score", 92); map2.put("age", 28); personList.add(new Person(new ArrayList<>(){{add(map2);}})); // 开始遍历比较,避免重复 for (int i = 0; i < personList.size() - 1; i++) { Person personA = personList.get(i); // 内层从i+1开始,确保只比较A和B,不会反过来 for (int j = i + 1; j < personList.size(); j++) { Person personB = personList.get(j); compareAndCalculateDifference(personA, personB); } } } private static void compareAndCalculateDifference(Person personA, Person personB) { // 先把每个Person的所有HashMap合并成一个统一的Map,方便比较 Map<String, Integer> combinedA = mergeMaps(personA.getDataMaps()); Map<String, Integer> combinedB = mergeMaps(personB.getDataMaps()); // 遍历A的所有key,查找B中存在的相同key并计算差值 for (Map.Entry<String, Integer> entry : combinedA.entrySet()) { String key = entry.getKey(); if (combinedB.containsKey(key)) { Integer valueA = entry.getValue(); Integer valueB = combinedB.get(key); // 处理可能的null值(如果你的场景中value可能为null的话) if (valueA != null && valueB != null) { int difference = Math.abs(valueA - valueB); // 差值取绝对值,可根据需求调整 System.out.printf("Person A与Person B的key【%s】差值为:%d%n", key, difference); // 这里可以把结果存入集合或数据库,而不是打印 } else { System.out.printf("Person A或Person B的key【%s】值为null,跳过比较%n", key); } } } } private static Map<String, Integer> mergeMaps(List<HashMap<String, Integer>> mapList) { Map<String, Integer> combinedMap = new HashMap<>(); for (HashMap<String, Integer> map : mapList) { // 如果同一个Person的多个HashMap中有重复key,这里会用后面的value覆盖前面的 // 如果需要累加重复key的值,把putAll改成下面的merge逻辑: // for (Map.Entry<String, Integer> entry : map.entrySet()) { // combinedMap.merge(entry.getKey(), entry.getValue(), Integer::sum); // } combinedMap.putAll(map); } return combinedMap; } }
关键细节说明
- 重复比较的避免:通过
i从0到size-2,j从i+1到size-1的循环逻辑,确保每一对(personA, personB)只会被处理一次,不会出现反向的重复比较,同时也跳过了自己和自己的比较。 - HashMap的合并:把一个Person的多个HashMap合并成一个,是为了简化后续的key匹配逻辑,不用嵌套多层循环遍历每个HashMap。如果你的场景中同一个Person的多个HashMap里有重复key,记得根据需求调整合并逻辑(是覆盖还是累加)。
- 边界情况处理:代码里加了null值的判断,如果你的业务场景中Integer值不会为null,可以去掉这部分判断;如果需要保留差值的正负(比如A-B还是B-A),去掉
Math.abs()即可。
内容的提问来源于stack exchange,提问作者mrsr
相关产品推荐
相关产品推荐

