根据每个键对应的列表里所有实体的 count 最大值,将整个字典从大到小重新排列

java 复制代码
Map<String, List<MyEntity>> sortedMapByMaxCount = originalMap.entrySet().stream()
    .sorted(Comparator.comparingInt(
        (Map.Entry<String, List<MyEntity>> entry) -> // 显式声明entry的类型
            entry.getValue().stream()
                .mapToInt(MyEntity::getCount)
                .max()
                .orElse(0)
    ).reversed())
    .collect(Collectors.toMap(
        Map.Entry::getKey,
        Map.Entry::getValue,
        (e1, e2) -> e1,
        LinkedHashMap::new
    ));

核心逻辑是:根据每个 key 对应的 value(即 List<MyEntity>)中某个字段(count)的最大值,来对整个 Map 的键值对(Entry)进行从大到小的排序,并将排序后的结果存入一个新的、能保持顺序的 Map 中。

为了更直观地理解,我们来看一个例子。假设原始的 originalMap如下:

key(字符串) value(List<MyEntity> 中各实体的 count 值) 列表中的最大 count
"A" count=3, count=5, count=1 5
"B" count=10 10
"C" count=7, count=2 7

执行代码后,新的 sortedMapByMaxCount中的键值对顺序将是:

key(字符串) value(List<MyEntity>) 排序依据(列表最大count)
"B" count=10 10
"C" count=7, count=2 7
"A" count=3, count=5, count=1 5

代码关键步骤解析

  1. 提取最大值作为排序依据 :对于 Map 中的每一个键值对(Entry),代码会取出其 value(即 List<MyEntity>),然后通过流式处理(stream())将其转换为一个整数流(mapToInt(MyEntity::getCount)),并找出这个列表里所有 count值中的最大值(max())。如果列表为空,则提供一个默认值 0(orElse(0))。

  2. 按最大值进行降序排序 :Comparator.comparingInt会基于上一步计算出的每个列表的最大整数值来创建比较器。紧随其后的 .reversed()方法则将比较顺序反转,从而实现**从大到小(降序)**​ 的排列。

  3. 收集到有序Map :最后,使用 Collectors.toMap并将一个 LinkedHashMap::new作为参数传入。这一步至关重要,因为普通的 HashMap不保证存储顺序,而 LinkedHashMap可以严格按照元素被放入的顺序(即我们刚刚排好的顺序)来存储和遍历键值对 。合并函数 (e1, e2) -> e1解决了可能的键冲突,这里通常保留第一个值。

重要辨析

  • key 本身没有变 :请注意,排序过程并没有改变 key 字符串本身 ("A"、"B"、"C" 还是原来的值)。改变的是这些 key 及其对应的 value 在整个 Map 中的相对位置顺序。

  • 排序的依据是 value 的特征 :决定顺序的不是 key 的字母或数字顺序,而是 key 所对应的 value(列表)中的一个内部特征(count字段的最大值)。这正是根据 Map 的 value 进行排序的典型场景。

  • 前端展示顺序问题 :如果你的这个 Map 最终要通过 Spring Boot 等框架以 JSON 格式返回给前端,即使后端使用了 LinkedHashMap,前端接收到的 JSON 对象属性顺序仍有可能被打乱,因为标准的 JSON 对象是无序的。如果顺序对前端展示至关重要,更可靠的方法是返回一个由键值对组成的列表(List<Map.Entry...>)或自定义对象的列表。

相关推荐
Z21-X24 分钟前
云原生运维学习笔记:ECShop全链路容器化部署与Docker底层资源隔离深度剖析
运维·笔记·学习·云原生
Zucker n1 小时前
文献发现、课题组织与证据可追溯的论文阅读。
论文阅读·windows·ubuntu
陈希1232 小时前
Linux 网络诊断工具实战:ping、curl、tcpdump、mtr、dig 用法详解
linux·网络·tcpdump
进击的荆棘2 小时前
Linux系统——线程同步与互斥之线程池和安全
linux·运维·服务器·安全·单例模式·线程
刘大望3 小时前
不用买开发板:用 QEMU 走通嵌入式 Linux 全流程(三)存储与网络实地验证
linux·qemu·嵌入式linux·alpine
瑞雪兆丰年兮3 小时前
JavaWeb-day11-SpringBootWeb案例(文件上传)
java·运维·服务器·javaweb·oss
那明眸似水4 小时前
云原生项目三:Docker秒级启动NextCloud个人网盘存储办公系统
linux·运维·docker·云原生·容器
小南家的青蛙5 小时前
微服务体系下DevOps运维岗位面试方案设计
运维·面试·职场和发展·devops
知已难寻15 小时前
Docker 入门:容器技术与 Docker 基础
java·运维·服务器·docker·云原生·容器
默|笙15 小时前
【Linux网络】网络层协议 IP(1)理解报头、网段划分
linux·网络·tcp/ip