Part 5 映射 Map
约 838 字大约 3 分钟
2025-05-21
Map 用于存储键值对。实现了Map
接口的容器可以分为基于哈希表的 HashMap 和基于红黑树的 TreeMap。
1 HashMap
哈希表并非铁板一块,而是分为线程安全的 HashTable 和线程不安全的 HashMap。由于前者是一个遗留类,因此现代开发中不应该使用 HashTable。如果有线程安全的要求,应该使用 ConcurrentHashMap。
在使用 HashMap 前,需要先导入:
import java.util.HashMap;
1.1 创建一个 HashMap
你需要在声明 HashMap 时分别指定键和值的数据类型,即K
和V
。同样,K
和V
只能是引用数据类型。
HashMap<K, V> map = new HashMap<>();
1.2 添加键值对
使用.put()
方法向 HashMap 中添加键值对。
map.put("name", "yoake");
map.put("age", "18");
System.out.println(map.toString()); // {name=yoake, age=18}
1.3 访问值
使用.get()
方法访问指定键的值。
System.out.println(map.get("name")); // yoake
1.4 修改值
使用.put()
方法修改指定键的值。
System.out.println(map.toString()); // {name=yoake, age=18}
map.put("name", "YOAKE");
System.out.println(map.toString()); // {name=YOAKE, age=18}
1.5 删除键值对
使用.remove()
从 HashMap 中删除键值对。
map.remove("name");
System.out.println(map.toString()); // {age=18}
2 TreeMap
TreeMap 基于红黑树实现,可以保证键的顺序。
在使用 TreeMap 之前,应该先导入:
import java.util.TreeMap;
2.1 TreeMap 的基本使用
TreeMap 的创建方法与 HashMap 类似。
TreeMap<String, String> map = new TreeMap<>();
TreeMap 同样使用.put()
方法添加(修改)键值对、使用.get()
方法访问指定键的值、使用.remove()
方法删除键值对。
map.put("3", "C");
map.put("1", "A");
map.put("4", "D");
map.put("2", "B");
System.out.println(map.toString()); // {1=A, 2=B, 3=C, 4=D}
map.put("1", "A1");
System.out.println(map.get("1")); // A1
map.remove("2");
System.out.println(map.toString()); // {1=A1, 3=C, 4=D}
从这里可以看出,TreeMap 内部确实是有顺序的。
2.2 改变排序方式
TreeMap 默认使用的是小顶堆,即按照键的自然顺序从小到大排列。
要按照键的自然属性从大到小排列,只要向构造函数传入Collections.reverseOrder()
作为比较器即可。
当然需要先导入Collections
。
import java.util.Collections;
map.put("3", "C");
map.put("1", "A");
map.put("4", "D");
map.put("2", "B");
System.out.println(map.toString()); // {4=D, 3=C, 2=B, 1=A}
2.3 TreeMap 的特有方法
得益于内部键有序,TreeMap 提供了一些特有方法。
2.3.1 查找最小/最大键
使用.firstKey()
和.lastKey()
查找 TreeMap 中的最小/最大键。这里的“最小”“最大”均为默认小顶堆排序。
System.out.println(map.toString()); // {1=A, 2=B, 3=C, 4=D, 5=E, 6=F}
System.out.println(map.firstKey()); // 1
System.out.println(map.lastKey()); // 6
2.3.2 查找范围内的最大/最小键
使用.higherKey()
查找严格大于(>)指定键的最小键。
使用.lowerKey()
查找严格小于(<)指定键的最大键。
使用.ceilingKey()
查找大于等于(>=)指定键的最小键。
使用.floorKey()
查找小于等于(<=)指定键的最大键。
System.out.println(map.toString()); // {1=A, 2=B, 3=C, 4=D, 5=E, 6=F}
System.out.println(map.higherKey("4")); // 5
System.out.println(map.lowerKey("3")); // 2
System.out.println(map.ceilingKey("4")); // 4
System.out.println(map.floorKey("3")); // 3
2.3.3 返回范围内的子映射
使用.subMap()
获取范围内的子映射。需要注意的是,返回的子映射类型并非为 TreeMap,而是 SortedMap。
因此使用之前需要先导入:
import java.util.SortedMap;
System.out.println(map.toString()); // {1=A, 2=B, 3=C, 4=D, 5=E, 6=F}
SortedMap<String, String> subMap = map.subMap("2", "5");
System.out.println(subMap.toString()); // {2=B, 3=C, 4=D}