Java Map 集合详解
Map
是 Java 集合框架中的一个接口,它并不继承自 Collection
,而是用于存储 键值对(Key-Value),其中每个键(Key)对应一个值(Value)。Map
是一个 无序 集合,不允许键重复,但值(Value)可以重复。
✅ 1. Map 的特点
- 无序性:
Map
的键值对没有固定的顺序,具体顺序由实现类决定。
- 键唯一性:
Map
中的每个键都是唯一的。如果插入具有相同键的条目,后插入的值会替代之前的值。
- 值可重复:
Map
中的值(Value)可以重复,但键(Key)不可重复。
✅ 2. Map 的主要实现类
实现类 |
底层数据结构 |
特点 |
HashMap |
哈希表(HashMap ) |
无序,查询、插入、删除时间复杂度 O(1) |
LinkedHashMap |
哈希表 + 双向链表 |
有序(按插入顺序) |
TreeMap |
红黑树(自平衡二叉树) |
有序(按自然排序或比较器排序) |
Hashtable |
哈希表 |
线程安全,性能较低(已废弃) |
ConcurrentHashMap |
哈希表(线程安全) |
线程安全,高性能 |
✅ 3. Map 的常用方法
方法 |
作用 |
put(K key, V value) |
添加键值对(如果键已存在,会替换对应的值) |
get(Object key) |
获取指定键对应的值 |
remove(Object key) |
删除指定键对应的键值对 |
containsKey(Object key) |
判断 Map 是否包含指定键 |
containsValue(Object value) |
判断 Map 是否包含指定值 |
size() |
获取 Map 中键值对的数量 |
isEmpty() |
判断 Map 是否为空 |
clear() |
清空 Map 中所有的键值对 |
keySet() |
获取 Map 中所有的键,返回一个 Set |
values() |
获取 Map 中所有的值,返回一个 Collection |
entrySet() |
获取 Map 中所有的键值对,返回一个 Set |
✅ 4. HashMap
用法
HashMap
基于 哈希表 实现,无序,线程不安全,查询和插入的时间复杂度为 O(1)。
4.1 HashMap
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import java.util.HashMap; import java.util.Map;
public class HashMapExample { public static void main(String[] args) { Map<String, String> map = new HashMap<>();
map.put("Java", "OOP Language"); map.put("Python", "Scripting Language"); map.put("C++", "Compiled Language");
System.out.println(map);
System.out.println("Java's description: " + map.get("Java"));
map.remove("Python"); System.out.println(map); } }
|
4.2 遍历 HashMap
方式 1:通过 keySet()
遍历键
1 2 3
| for (String key : map.keySet()) { System.out.println(key + ": " + map.get(key)); }
|
方式 2:通过 entrySet()
遍历键值对
1 2 3
| for (Map.Entry<String, String> entry : map.entrySet()) { System.out.println(entry.getKey() + ": " + entry.getValue()); }
|
方式 3:通过 forEach
(Java 8 Lambda)
1
| map.forEach((key, value) -> System.out.println(key + ": " + value));
|
✅ 5. LinkedHashMap
用法
LinkedHashMap
基于 哈希表 + 双向链表 实现,保持元素的插入顺序。
5.1 LinkedHashMap
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import java.util.LinkedHashMap; import java.util.Map;
public class LinkedHashMapExample { public static void main(String[] args) { Map<String, String> map = new LinkedHashMap<>();
map.put("Java", "OOP Language"); map.put("Python", "Scripting Language"); map.put("C++", "Compiled Language");
System.out.println(map); } }
|
5.2 按访问顺序排序
LinkedHashMap
还可以根据访问顺序排序,使用构造函数 LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder)
中的 accessOrder
参数设置为 true
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import java.util.LinkedHashMap; import java.util.Map;
public class LinkedHashMapAccessOrderExample { public static void main(String[] args) { Map<String, String> map = new LinkedHashMap<>(16, 0.75f, true);
map.put("Java", "OOP Language"); map.put("Python", "Scripting Language"); map.put("C++", "Compiled Language");
map.get("Python");
System.out.println(map); } }
|
✅ 6. TreeMap
用法
TreeMap
基于 红黑树 实现,按照键的自然顺序或根据提供的比较器排序,增删查的时间复杂度为 O(log n)。
6.1 TreeMap
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import java.util.Map; import java.util.TreeMap;
public class TreeMapExample { public static void main(String[] args) { Map<String, String> map = new TreeMap<>();
map.put("Java", "OOP Language"); map.put("Python", "Scripting Language"); map.put("C++", "Compiled Language");
System.out.println(map); } }
|
6.2 自定义排序
可以通过 Comparator
来指定排序规则:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import java.util.Comparator; import java.util.Map; import java.util.TreeMap;
public class CustomTreeMap { public static void main(String[] args) { Map<String, String> map = new TreeMap<>(Comparator.reverseOrder());
map.put("Java", "OOP Language"); map.put("Python", "Scripting Language"); map.put("C++", "Compiled Language");
System.out.println(map); } }
|
✅ 7. Hashtable
和 ConcurrentHashMap
Hashtable
:基于哈希表实现的线程安全的 Map
,它的所有方法都是同步的,性能较差,已被废弃,建议使用 ConcurrentHashMap
。
ConcurrentHashMap
:基于哈希表实现的 线程安全 Map
,具有更好的性能,因为它采用了分段锁的机制,允许多个线程并发操作。
✅ 8. Map vs Set vs List 对比
特性 |
Map |
Set |
List |
存储元素 |
键值对(Key-Value) |
单个元素 |
单个元素 |
是否允许重复 |
键不可重复,值可以重复 |
不允许重复 |
允许重复 |
是否有序 |
无序(HashMap )有序(LinkedHashMap , TreeMap ) |
无序(HashSet )有序(LinkedHashSet , TreeSet ) |
保持插入顺序 |
是否支持索引 |
❌ |
❌ |
✅ |
✅ 9. 总结
HashMap
:无序,查询插入删除快,线程不安全。
LinkedHashMap
:保持插入顺序,有序,查询插入删除较快。
TreeMap
:有序,按自然顺序或自
定义顺序排序,性能较低。
Hashtable
:线程安全,但性能较差,已被弃用。
ConcurrentHashMap
:线程安全,性能优越,适用于并发环境。