当前位置: 首页 > news >正文

深入理解Map.Entry.comparingByValue()和Map.Entry.comparingByKey()

文章目录

  • 深入理解Map.Entry.comparingByValue()和Map.Entry.comparingByKey()
    • 1. 方法定义
      • comparingByKey()
      • comparingByValue()
    • 2. 基本用法
      • 2.1 使用comparingByKey()
      • 2.2 使用comparingByValue()
    • 3. 方法重载版本
      • comparingByKey(Comparator)
      • comparingByValue(Comparator)
    • 4. 高级用法示例
      • 4.1 逆序排序
      • 4.2 自定义比较逻辑
      • 4.3 链式比较
    • 5. 与Collections.max/min结合使用
    • 6. 性能考虑
    • 7. 实际应用场景
      • 7.1 统计最高分学生
      • 7.2 商品按价格排序
      • 7.3 单词频率统计
    • 8. 注意事项
    • 9. 与相关方法的比较
    • 10. 总结


深入理解Map.Entry.comparingByValue()和Map.Entry.comparingByKey()

Java 8引入的Map.Entry.comparingByValue()Map.Entry.comparingByKey()是两个非常实用的比较器工厂方法,专门用于比较Map的条目(Entry)。本文将详细解析这两个方法的用法、区别以及实际应用场景。

1. 方法定义

comparingByKey()

public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K, V>> comparingByKey()
  • 创建一个按键的自然顺序比较Map条目的Comparator
  • 键类型K必须实现Comparable接口

comparingByValue()

public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K, V>> comparingByValue()
  • 创建一个按值的自然顺序比较Map条目的Comparator
  • 值类型V必须实现Comparable接口

2. 基本用法

2.1 使用comparingByKey()

Map<String, Integer> map = new HashMap<>();
map.put("Orange", 2);
map.put("Apple", 5);
map.put("Banana", 3);// 按键的自然顺序(字母顺序)排序
List<Map.Entry<String, Integer>> entries = new ArrayList<>(map.entrySet());
entries.sort(Map.Entry.comparingByKey());// 结果: Apple=5, Banana=3, Orange=2

2.2 使用comparingByValue()

// 按值的自然顺序(数值大小)排序
entries.sort(Map.Entry.comparingByValue());// 结果: Orange=2, Banana=3, Apple=5

3. 方法重载版本

这两个方法都有重载版本,允许传入自定义Comparator:

comparingByKey(Comparator)

public static <K, V> Comparator<Map.Entry<K, V>> comparingByKey(Comparator<? super K> cmp)

comparingByValue(Comparator)

public static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp)

4. 高级用法示例

4.1 逆序排序

// 按键逆序排序
entries.sort(Map.Entry.comparingByKey(Comparator.reverseOrder()));// 结果: Orange=2, Banana=3, Apple=5// 按值逆序排序
entries.sort(Map.Entry.comparingByValue(Comparator.reverseOrder()));// 结果: Apple=5, Banana=3, Orange=2

4.2 自定义比较逻辑

// 按键长度排序
entries.sort(Map.Entry.comparingByKey(Comparator.comparing(String::length)));// 按值的绝对值排序(假设值为Integer)
Map<String, Integer> numbers = Map.of("a", -3, "b", 2, "c", -5);
numbers.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.comparingInt(Math::abs))).forEach(System.out::println);

4.3 链式比较

// 先按值比较,值相同再按键比较
Comparator<Map.Entry<String, Integer>> comparator = Map.Entry.<String, Integer>comparingByValue().thenComparing(Map.Entry.comparingByKey());entries.sort(comparator);

5. 与Collections.max/min结合使用

Map<String, Integer> map = ...;// 找出值最大的条目
Map.Entry<String, Integer> maxEntry = Collections.max(map.entrySet(), Map.Entry.comparingByValue()
);// 找出键最小的条目
Map.Entry<String, Integer> minKeyEntry = Collections.min(map.entrySet(),Map.Entry.comparingByKey()
);

6. 性能考虑

  • 这些比较器本身不执行排序,只是定义比较规则
  • 实际排序性能取决于使用的排序算法(如Collections.sort是O(n log n))
  • 对于只需要最大/最小值的情况,使用Collections.max/min更高效(O(n))

7. 实际应用场景

7.1 统计最高分学生

Map<String, Integer> studentScores = ...;
String topStudent = Collections.max(studentScores.entrySet(),Map.Entry.comparingByValue()
).getKey();

7.2 商品按价格排序

Map<String, Double> products = ...;
List<Map.Entry<String, Double>> sortedProducts = products.entrySet().stream().sorted(Map.Entry.comparingByValue()).collect(Collectors.toList());

7.3 单词频率统计

Map<String, Integer> wordFrequency = ...;
// 找出频率最高的5个单词
List<String> topWords = wordFrequency.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).limit(5).map(Map.Entry::getKey).collect(Collectors.toList());

8. 注意事项

  1. 空值处理

    • 默认情况下,遇到null键或值会抛出NullPointerException
    • 可以使用Comparator.nullsFirst()或nullsLast()处理
    entries.sort(Map.Entry.comparingByValue(Comparator.nullsFirst(Comparator.naturalOrder())));
    
  2. 不可比较元素

    • 如果键或值没有实现Comparable且未提供Comparator,会抛出ClassCastException
  3. 不变性

    • 这些方法返回的Comparator是不可变的且线程安全的

9. 与相关方法的比较

方法特点适用场景
Map.Entry.comparingByKey()按键比较需要按键排序或查找
Map.Entry.comparingByValue()按值比较需要按值排序或查找
Comparator.comparing()通用比较需要自定义比较逻辑
Map.Entry.comparingByKey(Comparator)带自定义比较器需要特殊键比较逻辑
Map.Entry.comparingByValue(Comparator)带自定义比较器需要特殊值比较逻辑

10. 总结

Map.Entry.comparingByValue()Map.Entry.comparingByKey()是Java 8中处理Map排序和查找的利器:

  1. 代码简洁:避免了手动实现Comparator的繁琐
  2. 可读性强:方法名直接表达了比较的意图
  3. 灵活组合:可以与thenComparing等组合实现复杂比较逻辑
  4. 性能良好:与手动实现的Comparator性能相当

掌握这两个方法可以显著提高处理Map集合的效率和代码质量,特别是在需要排序或查找最大/最小元素的场景中。

http://www.dtcms.com/a/283648.html

相关文章:

  • Java中excel字典转换
  • Java 设计模式及应用场景
  • RocketMq集群高可用
  • ​​深入理解进程状态:从运行到僵尸​
  • 学习软件测试掌握什么基本知识?
  • 数字经济专业核心课程解析:从理论到实践的学习框架
  • C/C++---rdbuf()函数
  • parallels desktop windows win10无法复制文件无法共享剪切板
  • 利用node.js在本地搭建简易http服务器
  • QT跨平台应用程序开发框架(10)—— Qt窗口
  • 【C#】Vscode中C#工程如何引用自编写的dll
  • React hooks——useReducer
  • 端到端神经网络视频编解码器介绍
  • 神经网络常见激活函数 14-Mish函数
  • AI学习笔记三十二:YOLOv8-CPP-Inference测试(Linux版本)
  • CDSS系统升级“可视化解释-智能反馈-临床语言“三位一体设计架构设计分析
  • 「Chrome 开发环境快速屏蔽 CORS 跨域限制详细教程」*
  • lua(xlua)基础知识点记录二
  • Oracle数据泵详解——让数据迁移像“点外卖”一样简单​
  • 数据库管理-第349期 Oracle DB 23.9新特性一览(20250717)
  • python与正则:前后向断言、分组,以及案例练习
  • Xss-labs 1-8关的初步通关
  • 【Linux系统】进程地址空间
  • 时序数据库选型指南 —— 为什么选择 Apache IoTDB?
  • Qt Quick 粒子系统详解
  • 数据呈现高阶技巧:散点图与桑基图的独特价值
  • 从零开始学 Linux 系统安全:基础防护与实战应用
  • 12.9 Mixtral-8x7B核心技术解密:如何用1/3参数实现4倍推理速度碾压LLaMA2?
  • 取消office word中的段落箭头标记
  • 多方案对比分析:后端数据加密策略及实践