250. Java 集合 - 使用 Map 存储键值对

0 阅读3分钟

250. Java 集合 - 使用 Map 存储键值对


1. 🎯 键和值的基本关系规则

Map 中,**键(Key值(Value)**之间遵循两条非常重要的规则:

规则说明
一个键只能绑定一个值同一个键不能对应多个值
一个值可以被多个键绑定不同的键可以指向同一个值

2. 🧩 Map 中集合结构的对应关系

因此,Map 中各部分的结构特点是这样的:

组成部分特点对应的数据结构
所有的键(Keys无重复Set
所有的键值对(Entries无重复Set
所有的值(Values可以有重复Collection

✅ 小结:键和值的组合方式决定了 Map 的整体结构特性!


3. 🛠️ Map 支持的基本操作

在使用 Map 时,你可以进行以下常见操作:

操作描述
put(K key, V value)添加一个新的键值对(如果键已存在,会覆盖原值)
get(K key)根据键获取对应的值
remove(K key)移除指定键及其对应的值

同时还支持一些集合常见操作,比如:

操作描述
isEmpty()判断 Map 是否为空
size()获取 Map 中键值对数量
putAll(Map m)将另一个 Map 的内容全部放入当前 Map
clear()清空 Map 中所有数据

4. 🚀 示例演示

让我们用一个简单的小例子快速感受一下:

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

public class MapExample {
    public static void main(String[] args) {
        Map<String, String> countryCapital = new HashMap<>();

        // 添加元素
        countryCapital.put("China", "Beijing");
        countryCapital.put("Japan", "Tokyo");
        countryCapital.put("USA", "Washington");

        // 获取元素
        System.out.println("Capital of China: " + countryCapital.get("China")); // Beijing

        // 移除元素
        countryCapital.remove("Japan");

        // 判断是否为空
        System.out.println("Is map empty? " + countryCapital.isEmpty()); // false

        // 获取大小
        System.out.println("Map size: " + countryCapital.size()); // 2
    }
}

5. 🧠 深入:探索 Map 接口

JDK 中,Map 是建模"键值对结构"的核心接口

✨ 小提醒

使用 Map 时,一定要谨慎选择键的类型,特别是:

  • ⚡ 不推荐使用可变对象(mutable object)作为键!

如果一个对象作为键,且在放入 Map 后被修改,那么:

  • 它的 hashCode()equals() 可能变化
  • 导致 Map 无法正确找到它,甚至出现数据丢失现象!

❗ 例子:错误示范(使用可变对象做键)

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

class MutableKey {
        String keyPart;

        MutableKey(String keyPart) {
            this.keyPart = keyPart;
        }

        @Override
        public int hashCode() {
            return Objects.hash(keyPart);
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            MutableKey that = (MutableKey) o;
            return Objects.equals(keyPart, that.keyPart);
        }
}

public class MutableKeyDemo {
    public static void main(String[] args) {
        Map<MutableKey, String> map = new HashMap<>();

        MutableKey key = new MutableKey("initial");
        map.put(key, "Value1");

        System.out.println(map.get(key)); // 正常输出 Value1

        // 修改 key 对象的内容
        key.keyPart = "modified";

        // 再次尝试获取
        System.out.println(map.get(key)); // 输出 null!
    }
}
  • 原因:修改了 key 的属性,导致其 hashCode 变化Map 再也找不到这个键了!

✅ 正确做法:使用不可变对象(如 StringIntegerLong)作为 Map 的键!


6. 🧩 Map.Entry:建模单个键值对

在 Map 中,键值对被抽象成了内部接口:Map.Entry<K,V>

常见方法:

方法描述
getKey()获取键
getValue()获取值
setValue(V value)更新对应的值

注意

  • Entry 对象是 Map 内容的视图
  • 通过 Entry 修改值,直接影响原 Map 中的数据!
  • 不能直接修改键,否则会破坏 Map 的结构!

7. 🎯 小结

要点说明
一个键只能绑定一个值一个值可以绑定多个键
键和值的集合结构不同键是 Set,值是 Collection
Map 接口定义了丰富的方法put、get、remove、size、clear
不要用可变对象做键保持 Map 的稳定性

👀 培训互动问题

问题1:一个 Map 中可以有两个相同的键吗?

答案示例:不可以,键必须唯一,新值会覆盖旧值。

问题2:为什么不建议使用可变对象作为 Map 的键?

答案示例:因为对象变化后可能导致 hashCode 改变,导致 Map 无法正确找到原本的键值对。

问题3:通过 Map.Entry 修改值,会影响原 Map 吗?

答案示例:会,Entry 只是 Map 中元素的一个视图,修改会直接同步到原 Map。