【Java集合夜话】第9篇上:TreeMap详解,从基础到实战,一文掌握有序映射(建议收藏)

🔥 本文深入剖析Java集合框架中的TreeMap,从基础应用到实战案例,带你全面掌握这个重要的有序集合类。本文是TreeMap系列的上篇,主要关注基础用法与实战应用,下篇将深入源码与面试重点。

📚 系列专栏推荐:

我的java

一、TreeMap简介

1. 什么是TreeMap?

TreeMap是Java集合框架中的一个重要实现,它是一个基于红黑树实现的有序键值对集合。与HashMap不同,TreeMap可以保证其中的元素按照键的自然顺序或自定义顺序进行排序。

简单来说,TreeMap就像是一个会自动排序的Map,当你需要一个有序的键值对集合时,它就是最佳选择。

2. TreeMap的特点

2.1 有序性
TreeMap<String, Integer> treeMap = new TreeMap<>();
treeMap.put("banana", 2);
treeMap.put("apple", 1);
treeMap.put("orange", 3);

// 输出将按键的字母顺序排序:apple, banana, orange
System.out.println(treeMap); 
2.2 可自定义排序
// 自定义排序规则(按值降序)
TreeMap<String, Integer> customMap = new TreeMap<>((k1, k2) -> 
    treeMap.get(k2).compareTo(treeMap.get(k1)));
2.3 不允许null键
  • HashMap允许一个null键和多个null值
  • TreeMap不允许null键(会抛出NullPointerException),但允许null值
2.4 线程不安全
  • 多线程环境下需要外部同步
  • 可以使用Collections.synchronizedSortedMap()进行包装

3. 与HashMap的区别

特性 TreeMap HashMap
数据结构 红黑树 数组+链表+红黑树
有序性 有序 无序
性能 大部分操作 O(log n) 大部分操作 O(1)
null键 不支持 支持
内存占用 相对较大 相对较小
使用场景 需要排序的场景 一般键值对存储

4. 使用建议

  • 当需要按键排序时,使用TreeMap
  • 当不需要排序时,使用HashMap(性能更好)
  • 数据量大且需要排序时,考虑先用HashMap存储,需要时再排序
  • 需要频繁按序遍历时,TreeMap是好选择

💡 小贴士:TreeMap的有序性是以性能为代价的,如果你不需要有序性,建议使用HashMap。

5. 常见应用场景

  • 词频统计与排序
TreeMap<String, Integer> wordCount = new TreeMap<>();
String text = "hello world hello java";
for (String word : text.split(" ")) {
   
   
    wordCount.put(word, wordCount.getOrDefault(word, 0) + 1);
}
// 自动按单词字母顺序排序输出
System.out.println(wordCount); // {hello=2, java=1, world=1}
  • 范围查询
TreeMap<Integer, String> prices = new TreeMap<>();
prices.put(100, "商品A");
prices.put(200, "商品B");
prices.put(300, "商品C");

// 获取价格在200以下的商品
System.out.println(prices.headMap(200)); // {100=商品A}

6. 性能注意事项

  • 插入/删除/查找操作的时间复杂度均为O(log n)
  • 数据量较大时,性能差异会更明显
  • 如果不需要排序功能,优先使用HashMap
  • 对于需要频繁修改的场景,要谨慎使用

二、基础用法详解

1. 创建TreeMap

TreeMap提供了多种构造方法,让我们来看看最常用的几种:

// 1. 默认构造,按键的自然顺序排序
TreeMap<String, Integer> map1 = new TreeMap<>();

// 2. 使用比较器构造,自定义排序规则
TreeMap<String, Integer> map2 = new TreeMap<>((s1, s2) -> s2.compareTo(s1)); // 反序

// 3. 从已有Map构造
Map<String, Integer> existingMap = new HashMap<>();
TreeMap<String, Integer> map3 = new TreeMap<>(existingMap);

2. 增删改查操作

2.1 添加元素
TreeMap<String, Integer> scores = new TreeMap<>();
// 添加单个元素
scores.put("张三", 95);
scores.put("李四", 88);

// 批量添加
Map<String, Integer> newScores = new HashMap<>();
newScores.put("王五", 90);
newScores.put("赵六", 85);
scores.putAll(newScores);
2.2 删除元素
// 根据键删除
scores.remove("张三");

// 条件删除
scores.remove("李四", 88);  // 只有当值为88时才删除

// 清空所有
scores.clear();
2.3 修改元素
// 直接修改
scores.put("张三", 96);  // 覆盖原有值

// 计算并修改
scores.compute("张三", (k, v) -> v + 2);  // 加2分
scores.computeIfPresent("张三", (k, v) -> v + 2);  // 存在时才修改
scores.computeIfAbsent("张三", k -> 60);  // 不存在时才添加
2.4 查询元素
// 获取单个值
Integer score = scores.get("张三");
Integer defaultScore = scores.getOrDefault("王五", 0);

// 检查存在
boolean hasKey = scores.containsKey("张三");
boolean hasValue = scores.containsValue(95);

// 获取大小
int size = scores.size();
boolean isEmpty = scores.isEmpty();

3. 有序遍历方式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值