按值列表大小排序String-List<String> HashMap失败,求解决
问题分析与解决方案
你的Comparator核心逻辑没问题,但可能因为几个细节没处理导致未生效或结果不符合预期,以下是问题点和修正方案:
可能的问题点
- 空值未处理:如果Map中存在value为
null的Entry,调用size()会直接抛出空指针异常,导致排序失败。 - 同长度Entry的顺序不稳定:你的预期中,长度相同的
Test1和Test5按键的字典序排列,但原代码在长度相同时返回0,排序后的顺序可能随机。 - 未正确使用排序后的列表:若排序后仍遍历原HashMap(本身无序),自然看不到排序效果,必须用排序后的
List<Map.Entry>输出结果。
修正后的传统写法
List<Map.Entry<String, List<String>>> list = new ArrayList<>(map.entrySet()); Collections.sort(list, new Comparator<Map.Entry<String, List<String>>>() { public int compare(Map.Entry<String, List<String>> o1, Map.Entry<String, List<String>> o2) { // 处理空列表,将null视为长度0 int size1 = o1.getValue() == null ? 0 : o1.getValue().size(); int size2 = o2.getValue() == null ? 0 : o2.getValue().size(); // 先按列表长度升序,长度相同则按键的字典序升序 if (size1 != size2) { return Integer.compare(size1, size2); } else { return o1.getKey().compareTo(o2.getKey()); } } }); // 遍历排序后的列表输出结果 for (Map.Entry<String, List<String>> entry : list) { System.out.println(entry.getKey() + "-" + String.join(",", entry.getValue())); }
Java 8+ 简化写法(Stream API)
如果使用Java 8及以上版本,用Stream排序更简洁:
map.entrySet() .stream() .sorted((o1, o2) -> { int size1 = o1.getValue() == null ? 0 : o1.getValue().size(); int size2 = o2.getValue() == null ? 0 : o2.getValue().size(); if (size1 != size2) { return Integer.compare(size1, size2); } return o1.getKey().compareTo(o2.getKey()); }) .forEach(entry -> System.out.println(entry.getKey() + "-" + String.join(",", entry.getValue())));
验证结果
用你给出的示例Map测试,两种写法都会输出符合预期的结果:
Test3-f Test1-a,b Test5-p,b Test2-c,d,e Test4-d,g,h,i
内容的提问来源于stack exchange,提问作者recovery 69
相关产品推荐
相关产品推荐

