You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用匿名类Comparator通过Collections.sort对Map按值排序遇问题求助

解决Map按值排序的问题

嘿,我来帮你搞明白为啥你的HashMap按值排序行不通~

首先得明确一个关键点:HashMap本身是完全无序的,它基于哈希表实现,元素的存储位置由键的哈希值决定,既不维护插入顺序,也不会自动保持任何排序后的顺序。所以你直接对HashMap做排序操作是看不到效果的,因为它根本就没地方存这个排序后的顺序嘛!

那正确的做法应该是把Map里的条目(Entry)提取出来,放到可以排序的集合里处理,再把结果存到一个能保留顺序的Map实现里(比如LinkedHashMap)。下面给你两种常用的实现方式:

方式一:传统Collections.sort写法(兼容Java 7及以下)

先把Map的entrySet转成ArrayList,然后用Collections.sort结合自定义的Comparator来按值排序,最后把排序后的条目存入LinkedHashMap保留顺序:

import java.util.*;

public class Test {
    public static void main(String[] args) {
        Map<Integer, Integer> map = new HashMap<>();
        map.put(1,4);
        map.put(2,3);
        map.put(5,1);
        map.put(7,0);
        map.put(4,4);
        map.put(9,1);

        // 1. 将Map的条目转成可排序的List
        List<Map.Entry<Integer, Integer>> entryList = new ArrayList<>(map.entrySet());

        // 2. 自定义排序规则:先按值升序,值相同时按键升序
        Collections.sort(entryList, new Comparator<Map.Entry<Integer, Integer>>() {
            @Override
            public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) {
                // 先比较值
                int valueCompare = o1.getValue().compareTo(o2.getValue());
                // 值相同的话,再比较键
                if (valueCompare == 0) {
                    return o1.getKey().compareTo(o2.getKey());
                }
                return valueCompare;
            }
        });

        // 3. 将排序后的条目存入LinkedHashMap,保留顺序
        Map<Integer, Integer> sortedMap = new LinkedHashMap<>();
        for (Map.Entry<Integer, Integer> entry : entryList) {
            sortedMap.put(entry.getKey(), entry.getValue());
        }

        // 打印验证结果
        for (Map.Entry<Integer, Integer> entry : sortedMap.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }
}

方式二:Java 8+流式API写法(更简洁)

用流式API可以一行完成排序和收集,代码更简洁:

import java.util.*;
import java.util.stream.Collectors;

public class Test {
    public static void main(String[] args) {
        Map<Integer, Integer> map = new HashMap<>();
        map.put(1,4);
        map.put(2,3);
        map.put(5,1);
        map.put(7,0);
        map.put(4,4);
        map.put(9,1);

        // 流式排序+收集到LinkedHashMap
        Map<Integer, Integer> sortedMap = map.entrySet()
                .stream()
                // 先按值升序,值相同则按键升序
                .sorted(Map.Entry.<Integer, Integer>comparingByValue()
                        .thenComparing(Map.Entry.comparingByKey()))
                // 收集到LinkedHashMap中,保证顺序
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        Map.Entry::getValue,
                        (oldVal, newVal) -> oldVal, // 键冲突时保留旧值(这里不会出现)
                        LinkedHashMap::new
                ));

        // 打印结果
        sortedMap.forEach((key, value) -> System.out.println(key + ": " + value));
    }
}

运行这两段代码,你都会得到按值升序排列的结果(值相同的按键升序):

7: 0
5: 1
9: 1
2: 3
1: 4
4: 4

总结一下:你之前的做法行不通,核心原因就是HashMap不维护任何顺序,必须借助可排序的集合(比如List)处理排序逻辑,再用LinkedHashMap来保存排序后的顺序。

内容的提问来源于stack exchange,提问作者Greg1oo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:12:14