当前位置: 首页 > 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.lryc.cn/news/591220.html

相关文章:

  • 我爱学算法之—— 前缀和(下)
  • 第十四章 gin基础
  • 深入理解React Hooks:从使用到原理
  • Qt CMake 学习文档
  • 【安卓按键精灵辅助工具】adb调试工具连接安卓模拟器异常处理
  • QT之openGL使用(二)
  • 端到端神经网络视频编解码器介绍
  • 电脑截图软件排行榜 Windows和mac电脑截图软件TOP10
  • 基于Rust游戏引擎实践(Game)
  • ZKmall开源商城架构助力增长:多端流量聚合与用户体验
  • Web3智能合约技术论述
  • NLP-文本预处理
  • centos 新加磁盘分区动态扩容
  • 什么是 M4A 和 WAV?这两种音频互转会导致音质发生变化吗
  • PySide笔记之信号连接信号
  • 解锁 iOS 按键精灵辅助工具自动化新可能:iOSElement.Click 让元素交互更简单
  • 初识 二叉树
  • iOS 构建配置与 AdHoc 打包说明
  • 设计模式四:装饰模式(Decorator Pattern)
  • 拿到安全工程师证后,能从事哪些岗位?
  • 十六进制与嵌入式系统及通信系统
  • 量化环节剖析
  • 暑期自学嵌入式——Day05(C语言阶段)
  • Oracle Data Pump 导入冲突解决
  • 九学王资源apk应用名称整理
  • 从平面到时空:地图故事的时空叙事与沉浸式阅读
  • 从单线程到云原生:Redis 二十年演进全景与内在机理深剖
  • Spring之【BeanDefinition】
  • 图片画廊浏览(侧重 CSS 网格布局和模态框交互)
  • 在分布式系统中,如何保证缓存与数据库的数据一致性?