Java Map集合 #

一、Map接口 #

1.1 特点 #

  • 存储键值对(Key-Value)
  • 键不可重复
  • 值可以重复

1.2 常用方法 #

java
Map<String, Integer> map = new HashMap<>();

// 添加
map.put("A", 1);
map.put("B", 2);
map.putIfAbsent("C", 3);  // 键不存在时添加

// 获取
Integer value = map.get("A");
Integer defaultValue = map.getOrDefault("D", 0);

// 删除
map.remove("A");
map.remove("B", 2);  // 键值都匹配才删除

// 判断
map.containsKey("A");
map.containsValue(1);
map.isEmpty();
map.size();

// 替换
map.replace("A", 10);
map.replace("A", 10, 20);  // 旧值匹配才替换

// 清空
map.clear();

二、HashMap #

2.1 特点 #

  • 基于哈希表实现
  • 键和值都允许null
  • 非线程安全
  • 查找效率高

2.2 基本使用 #

java
Map<String, Integer> map = new HashMap<>();

// 添加
map.put("张三", 25);
map.put("李四", 30);
map.put("王五", 28);

// 获取
System.out.println(map.get("张三"));  // 25
System.out.println(map.get("赵六"));  // null

// 遍历键
for (String key : map.keySet()) {
    System.out.println(key + ": " + map.get(key));
}

// 遍历值
for (Integer value : map.values()) {
    System.out.println(value);
}

// 遍历键值对
for (Map.Entry<String, Integer> entry : map.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

// forEach
map.forEach((k, v) -> System.out.println(k + ": " + v));

2.3 常用操作 #

java
Map<String, Integer> map = new HashMap<>();

// 批量添加
Map<String, Integer> other = new HashMap<>();
other.put("A", 1);
other.put("B", 2);
map.putAll(other);

// 计算方法
map.compute("A", (k, v) -> v == null ? 1 : v + 1);
map.computeIfAbsent("B", k -> 2);  // 键不存在时计算
map.computeIfPresent("A", (k, v) -> v * 2);  // 键存在时计算

// 合并
map.merge("A", 1, Integer::sum);  // 存在则相加,不存在则设置

三、LinkedHashMap #

3.1 特点 #

  • 保持插入顺序
  • 可以按访问顺序排序
  • 性能略低于HashMap

3.2 基本使用 #

java
Map<String, Integer> map = new LinkedHashMap<>();

map.put("C", 3);
map.put("A", 1);
map.put("B", 2);

System.out.println(map);  // {C=3, A=1, B=2}(保持插入顺序)

3.3 LRU缓存 #

java
public class LRUCache<K, V> extends LinkedHashMap<K, V> {
    private final int maxSize;
    
    public LRUCache(int maxSize) {
        super(maxSize, 0.75f, true);  // accessOrder=true
        this.maxSize = maxSize;
    }
    
    @Override
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        return size() > maxSize;
    }
}

// 使用
LRUCache<String, String> cache = new LRUCache<>(3);
cache.put("A", "1");
cache.put("B", "2");
cache.put("C", "3");
cache.get("A");  // 访问A
cache.put("D", "4");  // B会被移除(最久未访问)
System.out.println(cache);  // {C=3, A=1, D=4}

四、TreeMap #

4.1 特点 #

  • 基于红黑树实现
  • 键自然排序
  • 键不允许null

4.2 基本使用 #

java
Map<String, Integer> map = new TreeMap<>();

map.put("C", 3);
map.put("A", 1);
map.put("B", 2);

System.out.println(map);  // {A=1, B=2, C=3}(按键排序)

4.3 自定义排序 #

java
// 降序
Map<String, Integer> map = new TreeMap<>(Comparator.reverseOrder());

// 按值排序
Map<String, Integer> map = new TreeMap<>();
map.put("A", 3);
map.put("B", 1);
map.put("C", 2);

List<Map.Entry<String, Integer>> list = new ArrayList<>(map.entrySet());
list.sort(Map.Entry.comparingByValue());

4.4 NavigableMap方法 #

java
TreeMap<String, Integer> map = new TreeMap<>();
map.put("A", 1);
map.put("C", 3);
map.put("E", 5);

// 查找
System.out.println(map.firstKey());      // A
System.out.println(map.lastKey());       // E
System.out.println(map.lowerKey("C"));   // A
System.out.println(map.higherKey("C"));  // E

// 子图
System.out.println(map.headMap("C"));    // {A=1}
System.out.println(map.tailMap("C"));    // {C=3, E=5}
System.out.println(map.subMap("A", "E")); // {A=1, C=3}

五、Map实现类对比 #

实现 底层 排序 性能 null键
HashMap 哈希表 无序 最高 允许
LinkedHashMap 哈希表+链表 插入/访问顺序 较高 允许
TreeMap 红黑树 键排序 较低 不允许
Hashtable 哈希表 无序 较低 不允许

六、遍历方式 #

6.1 遍历键 #

java
Map<String, Integer> map = new HashMap<>();
map.put("A", 1);
map.put("B", 2);

// 遍历键
for (String key : map.keySet()) {
    System.out.println(key + ": " + map.get(key));
}

6.2 遍历值 #

java
for (Integer value : map.values()) {
    System.out.println(value);
}

6.3 遍历键值对 #

java
// 推荐方式
for (Map.Entry<String, Integer> entry : map.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

// forEach
map.forEach((k, v) -> System.out.println(k + ": " + v));

// Stream
map.entrySet().stream()
    .filter(e -> e.getValue() > 1)
    .forEach(e -> System.out.println(e.getKey() + ": " + e.getValue()));

七、总结 #

实现 使用场景
HashMap 快速查找,不关心顺序
LinkedHashMap 需要保持顺序
TreeMap 需要按键排序
ConcurrentHashMap 多线程环境

Map要点:

  • HashMap最常用,性能最高
  • LinkedHashMap保持插入顺序
  • TreeMap按键排序
  • 遍历优先使用entrySet
最后更新:2026-03-26