TreeMap初始化异常:依赖键值的Comparator为何无法生效?
问题根源分析
你的代码无法运行的核心原因是TreeMap构造器接受的Comparator类型不匹配:
- TreeMap是基于键排序的SortedMap实现,它的构造器要求传入的Comparator必须是用来比较键类型(这里是
Country)的,即Comparator<Country>。 - 但你实现的
SortCountryChargers是用来比较Map.Entry<Country, Pair<Integer, Integer>>的,类型完全不兼容,这会直接导致编译错误。
另外还有一个逻辑误区:TreeMap的排序逻辑仅依赖键,和对应的值无关。就算你强行把Comparator改成兼容类型,后续修改Pair中的统计值时,TreeMap也不会自动重新排序,因为它的顺序是初始化时由键的比较规则决定的,值的变化不会影响排序。
修复方案
因为你需要根据**值的总和(Pair的两个元素之和)**来排序,TreeMap无法满足这个需求,正确的做法是:
- 先用普通的Map(比如HashMap)完成统计逻辑;
- 统计完成后,将Map的Entry集合取出,用自定义的Comparator进行排序。
以下是修改后的代码示例:
修改Ex4类的setCountryChargers方法
import java.util.*; import java.util.stream.Collectors; public class Ex4 { // 用List存储排序后的结果,更符合按值排序的需求 private static List<Map.Entry<Country, Pair<Integer, Integer>>> sortedCountryChargers; public static void setCountryChargers(Set<ChargingStation> chargingStationSet, int Kw) { // 第一步:用HashMap完成统计逻辑 Map<Country, Pair<Integer, Integer>> tempMap = new HashMap<>(); for (ChargingStation chargingStation : chargingStationSet) { Country country = chargingStation.getCountry(); // 简化判断:如果key不存在则初始化Pair tempMap.computeIfAbsent(country, k -> new Pair<>(0, 0)); Pair<Integer, Integer> pair = tempMap.get(country); if (chargingStation.getkW() > Kw) { pair.setFirst(pair.getFirst() + 1); } else { pair.setSecond(pair.getSecond() + 1); } } // 第二步:用自定义Comparator对Entry集合排序 sortedCountryChargers = tempMap.entrySet() .stream() .sorted(new SortCountryChargers()) .collect(Collectors.toList()); // 若必须用Map类型存储排序结果,可使用LinkedHashMap保留插入顺序 // Map<Country, Pair<Integer, Integer>> sortedMap = new LinkedHashMap<>(); // sortedCountryChargers.forEach(entry -> sortedMap.put(entry.getKey(), entry.getValue())); } }
保留原SortCountryChargers类(无需修改)
import java.util.Comparator; import java.util.Map; public class SortCountryChargers implements Comparator<Map.Entry<Country, Pair<Integer, Integer>>> { @Override public int compare(Map.Entry<Country, Pair<Integer, Integer>> object1, Map.Entry<Country, Pair<Integer, Integer>> object2) { int pair1 = sumPairs(object1.getValue()); int pair2 = sumPairs(object2.getValue()); if (pair1 > pair2) return 1; else if (pair1 < pair2) return -1; String country1 = object1.getKey().getName(); String country2 = object2.getKey().getName(); return country1.compareTo(country2); } public int sumPairs(Pair<Integer, Integer> p) { return p.getFirst() + p.getSecond(); } }
关键说明
- 使用HashMap统计数据:HashMap适合快速的增删改查,能高效完成统计需求;
- 排序阶段单独处理:通过Stream的
sorted方法,直接复用你已经实现的Entry比较器,完美匹配你的排序逻辑; - 若需Map类型存储排序结果:LinkedHashMap会保留元素的插入顺序,将排序后的Entry依次存入即可实现有序的Map结构。
内容的提问来源于stack exchange,提问作者Docas 95
相关产品推荐
相关产品推荐

