教程中心 / Java教程 / Map集合

Map集合

20分钟 集合框架

引言:什么是Map?

Map(映射)存储键值对(key-value)数据,可以通过键(key)快速找到对应的值(value)。

Map类比

Map就像一本字典:
┌─────────────┬───────────┐
│    键(Key)  │  值(Value) │
├─────────────┼───────────┤
│    "cat"    │   "猫"     │
│    "dog"    │   "狗"     │
│    "bird"   │   "鸟"     │
└─────────────┴───────────┘
通过"dog"这个键,可以快速找到"狗"这个值

Map的特点:

  • 键唯一:每个键最多只能对应一个值
  • 值可重复:不同的键可以对应相同的值
  • 键值对:存储的是key-value键值对

Map的主要实现类

实现类特点适用场景
HashMap基于哈希表,无序最常用,需要快速查找
LinkedHashMap基于哈希表+链表,保持插入顺序需要保持顺序
TreeMap基于红黑树,按key排序需要按key排序
Hashtable线程安全,已过时不推荐使用

HashMap的使用

创建HashMap

import java.util.HashMap;
import java.util.Map;

// 创建HashMap(推荐写法)
Map map = new HashMap<>();

添加元素 - put()

Map scores = new HashMap<>();

// 添加键值对
scores.put("张三", 95);
scores.put("李四", 88);
scores.put("王五", 92);

// key相同时,value会被覆盖
scores.put("张三", 100);  // 张三的成绩被更新为100

System.out.println(scores);  // {李四=88, 王五=92, 张三=100}

访问元素 - get()

Map scores = new HashMap<>();
scores.put("张三", 95);
scores.put("李四", 88);

// 通过key获取value
System.out.println(scores.get("张三"));  // 95
System.out.println(scores.get("王五"));  // null(key不存在)

// 安全获取:使用getOrDefault()
System.out.println(scores.getOrDefault("王五", 0));  // 0(key不存在时返回默认值)

删除元素 - remove()

Map scores = new HashMap<>();
scores.put("张三", 95);
scores.put("李四", 88);

// 按key删除
scores.remove("李四");
System.out.println(scores);  // {张三=95}

// 清空所有
scores.clear();
System.out.println(scores);  // {}

修改元素 - put()

Map scores = new HashMap<>();
scores.put("张三", 95);

// 修改:使用put()方法,如果key存在则覆盖value
scores.put("张三", 100);
System.out.println(scores.get("张三"));  // 100

判断方法

Map scores = new HashMap<>();
scores.put("张三", 95);

// 判断是否包含key
System.out.println(scores.containsKey("张三"));  // true
System.out.println(scores.containsKey("李四"));  // false

// 判断是否包含value
System.out.println(scores.containsValue(95));  // true
System.out.println(scores.containsValue(100));  // false

// 判断是否为空
System.out.println(scores.isEmpty());  // false

遍历Map的几种方式

方式1:遍历key

Map scores = new HashMap<>();
scores.put("张三", 95);
scores.put("李四", 88);
scores.put("王五", 92);

System.out.println("===== 遍历所有key =====");
for (String key : scores.keySet()) {
    System.out.println("key: " + key);
}

方式2:遍历value

System.out.println("===== 遍历所有value =====");
for (Integer value : scores.values()) {
    System.out.println("value: " + value);
}

方式3:遍历key-value(最常用)

System.out.println("===== 遍历key-value =====");
for (Map.Entry entry : scores.entrySet()) {
    String key = entry.getKey();
    Integer value = entry.getValue();
    System.out.println(key + " = " + value);
}

方式4:Java 8+的forEach

System.out.println("===== forEach方式 =====");
scores.forEach((key, value) -> {
    System.out.println(key + " = " + value);
});

TreeMap的使用

TreeMap基于红黑树实现,会按照key进行排序。

创建TreeMap

import java.util.TreeMap;
import java.util.Map;

Map treeMap = new TreeMap<>();

treeMap.put("banana", 2);
treeMap.put("apple", 5);
treeMap.put("orange", 3);

System.out.println(treeMap);
// 输出:{apple=5, banana=2, orange=3}
// 按key的字母顺序排列

TreeMap特有方法

TreeMap treeMap = new TreeMap<>();

treeMap.put("banana", 2);
treeMap.put("apple", 5);
treeMap.put("orange", 3);

// 获取第一个和最后一个key
System.out.println("第一个key: " + treeMap.firstKey());
System.out.println("最后一个key: " + treeMap.lastKey());

// 获取小于等于指定key的最大key
System.out.println("floorKey('orange'): " + treeMap.floorKey("orange"));

// 获取大于等于指定key的最小key
System.out.println("ceilingKey('orange'): " + treeMap.ceilingKey("orange"));

LinkedHashMap的使用

LinkedHashMap维护插入顺序,适合需要保持元素插入顺序的场景。

创建LinkedHashMap

import java.util.LinkedHashMap;
import java.util.Map;

Map linkedMap = new LinkedHashMap<>();

linkedMap.put("first", 1);
linkedMap.put("second", 2);
linkedMap.put("third", 3);

System.out.println(linkedMap);
// 输出:{first=1, second=2, third=3}
// 保持插入顺序

HashMap、TreeMap、LinkedHashMap对比

特性HashMapLinkedHashMapTreeMap
底层数据结构哈希表哈希表+链表红黑树
顺序无序插入顺序key排序顺序
查找速度O(1)O(1)O(log n)
key限制可为null可为null不能为null
适用场景最常用需要保持顺序需要排序

Map常用方法汇总

方法说明
put(K key, V value)添加键值对
get(Object key)通过key获取value
getOrDefault(K key, V defaultValue)安全获取,不存在返回默认值
remove(Object key)删除指定key的键值对
clear()清空所有键值对
containsKey(Object key)判断是否包含指定key
containsValue(Object value)判断是否包含指定value
keySet()获取所有key的集合
values()获取所有value的集合
entrySet()获取所有键值对的集合
size()获取键值对数量
isEmpty()判断是否为空

实战练习

练习:单词计数

import java.util.HashMap;
import java.util.Map;

public class WordCount {
    public static void main(String[] args) {
        String[] words = {"apple", "banana", "apple", "orange", "banana", "apple"};

        Map countMap = new HashMap<>();

        for (String word : words) {
            countMap.put(word, countMap.getOrDefault(word, 0) + 1);
        }

        System.out.println("===== 单词计数结果 =====");
        for (Map.Entry entry : countMap.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }
}

小结

  • Map存储键值对(key-value),通过key快速查找value
  • HashMap最常用,查找效率高,key无序
  • LinkedHashMap保持插入顺序
  • TreeMap按key排序
  • 遍历方式:keySet()、values()、entrySet()、forEach
☕ Java 在线代码编辑器
📝 运行结果