如何先按值再按键对HashMap排序(值重复场景下)
解决HashMap按值+键排序的方案
嘿,这个需求其实很好解决,核心就是自定义排序逻辑——先按值比较,值相同时再按键比较,咱们用Java来举个例子一步步拆解:
第一步:明确前提
HashMap本身是无序的,所以咱们得先把它的键值对(Entry)转成可排序的集合,比如ArrayList,再对这个集合进行排序。
第二步:自定义排序逻辑
这里分两种写法,传统匿名内部类和Java 8+的Lambda/链式调用,按需选择:
方式1:传统匿名内部类(兼容Java 7及以下)
// 先初始化一个示例HashMap HashMap<String, Integer> map = new HashMap<>(); map.put("banana", 2); map.put("apple", 1); map.put("cherry", 2); map.put("date", 3); // 把Entry转成List List<Map.Entry<String, Integer>> entryList = new ArrayList<>(map.entrySet()); // 自定义比较器:先比value,value相等再比key Collections.sort(entryList, new Comparator<Map.Entry<String, Integer>>() { @Override public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) { // 先按值升序排序(如果要降序就反过来:o2.getValue().compareTo(o1.getValue())) int valueCompare = o1.getValue().compareTo(o2.getValue()); if (valueCompare != 0) { return valueCompare; } // 值相等时,按键升序排序(同理,降序就o2.getKey().compareTo(o1.getKey())) return o1.getKey().compareTo(o2.getKey()); } });
方式2:Java 8+ 简化写法(Lambda/链式Comparator)
这种写法更简洁,推荐在Java 8及以上环境使用:
// 同样先初始化HashMap和转成List HashMap<String, Integer> map = new HashMap<>(); map.put("banana", 2); map.put("apple", 1); map.put("cherry", 2); map.put("date", 3); List<Map.Entry<String, Integer>> entryList = new ArrayList<>(map.entrySet()); // 链式调用:先按value排序,再按key排序 entryList.sort(Comparator.comparing(Map.Entry::getValue) .thenComparing(Map.Entry::getKey)); // 如果需要降序,只要加reversed()即可,比如先按value降序,再按key升序: // entryList.sort(Comparator.comparing(Map.Entry::getValue).reversed() // .thenComparing(Map.Entry::getKey));
第三步:保存排序后的结果(可选)
如果需要一个保持排序顺序的Map,可以把排序后的List转存到LinkedHashMap里(它会保留插入顺序):
LinkedHashMap<String, Integer> sortedMap = new LinkedHashMap<>(); for (Map.Entry<String, Integer> entry : entryList) { sortedMap.put(entry.getKey(), entry.getValue()); }
这样得到的sortedMap就是完全符合你需求的有序Map了——先按值排序,值相同的按键排序。
内容的提问来源于stack exchange,提问作者AbdallahRizk
相关产品推荐
相关产品推荐

