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); // {Java=OOP Language, Python=Scripting Language, C++=Compiled Language}

// 获取值
System.out.println("Java's description: " + map.get("Java")); // OOP Language

// 删除键值对
map.remove("Python");
System.out.println(map); // {Java=OOP Language, C++=Compiled Language}
}
}

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); // {Java=OOP Language, Python=Scripting Language, C++=Compiled Language}
}
}

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); // {Java=OOP Language, C++=Compiled Language, Python=Scripting Language}
}
}

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); // {C++=Compiled Language, Java=OOP Language, Python=Scripting Language}
}
}

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); // {Python=Scripting Language, Java=OOP Language, C++=Compiled Language}
}
}

7. HashtableConcurrentHashMap

  • 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:线程安全,性能优越,适用于并发环境。