深度拆解:ZYNQ_CORE_484核心板的电源与时钟树设计,如何影响你的系统稳定性?
2026/5/9 15:36:30
Map 是 Java 集合框架中双列集合的核心接口,隶属于java.util包,与Collection接口(单列集合)并列,专门用于存储 “键(Key)- 值(Value)” 映射关系。相较于单列集合,Map 更侧重 “通过键快速查找值” 的场景,其设计思想和底层原理是 Java 集合体系的核心知识点。
put方法的返回值特性)。hashCode()和equals()方法 —— 两个键对象若equals()返回true,且hashCode()返回值相同,则视为同一个键。HashMap、LinkedHashMap:允许键为null(仅允许一个),允许值为null(多个);Hashtable、ConcurrentHashMap:不允许键或值为null(避免空指针,适配多线程场景);TreeMap:键不能为null(依赖比较器 / 自然排序,null无法参与比较),值可以为null。hashCode();hash = key.hashCode() ^ (key.hashCode() >>> 16)(高位参与运算,减少哈希冲突);index = hash & (table.length - 1)(等价于取模,效率更高,前提是数组容量为 2 的幂)。resize())可能导致链表成环,插入 / 删除操作可能出现数据丢失;ConcurrentHashMap(JDK 8 后基于 CAS + synchronized 实现,性能优于Hashtable)。HashMap,底层额外维护一个双向链表,记录键值对的插入顺序 / 访问顺序;accessOrder = true实现 “访问顺序”(每次get/put访问的元素会移到链表尾部,适用于实现 LRU 缓存)。HashMap的Node节点,新增before和after指针,用于构建双向链表;newNode()、afterNodeAccess()、afterNodeInsertion()等方法,维护双向链表的节点顺序。Comparator排序,遍历结果始终有序。Comparable接口(自然排序),或创建TreeMap时指定Comparator(自定义排序);Comparable且无自定义比较器,调用put时会抛出ClassCastException。ceilingKey(K key):返回大于等于指定键的最小键;floorKey(K key):返回小于等于指定键的最大键;subMap(K fromKey, K toKey):获取键在指定范围的子 Map(视图,原 Map 变更会同步)。synchronized锁(锁整个对象,并发效率低);ConcurrentHashMap替代,仅兼容旧代码场景。HashMap结构类似;synchronized锁(锁粒度更小,并发效率更高);null,避免多线程下null值的歧义(无法区分 “键不存在” 和 “值为 null”)。| 遍历方式 | 实现方式 | 优点 | 缺点 |
|---|---|---|---|
| 键遍历(keySet ()) | for (K key : map.keySet()) { V value = map.get(key); } | 代码简洁 | 需两次哈希查找(keySet 遍历一次,get 一次),效率低 |
| 键值对遍历(entrySet ()) | for (Map.Entry<K,V> entry : map.entrySet()) { K key = entry.getKey(); V value = entry.getValue(); } | 一次遍历获取键值,效率最高 | 代码稍繁琐 |
| 迭代器遍历(Iterator) | Iterator<Map.Entry<K,V>> iterator = map.entrySet().iterator(); while (iterator.hasNext()) { ... } | 支持遍历中删除元素(iterator.remove ()) | 代码繁琐 |
| forEach 遍历(JDK 8+) | map.forEach((k, v) -> { ... }); | 函数式编程,代码简洁 | 无法遍历中删除元素(需用 removeIf) |
entrySet()遍历(仅一次哈希计算,直接获取键值对);keySet()+get()(两次哈希查找,哈希冲突时性能更差)。hashCode()和equals()equals():比较对象地址,导致即使内容相同的两个对象被视为不同键;hashCode():返回对象的内存地址哈希值,导致相同内容的对象哈希值不同,映射到不同数组桶。equals()返回true,则hashCode()必须返回相同值;若equals()返回false,hashCode()尽量返回不同值(减少哈希冲突);hashCode()的返回值在对象生命周期内不能改变(若键对象的属性参与哈希计算,需保证属性不可变,或避免修改参与计算的属性)。class Student { private String id; private String name; // 构造器、getter/setter 省略 // 重写 equals() @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; return Objects.equals(id, student.id); // 以唯一标识 id 作为判断依据 } // 重写 hashCode() @Override public int hashCode() { return Objects.hash(id); // 仅基于 id 计算哈希值 } } // 使用自定义对象作为键 Map<Student, Integer> scoreMap = new HashMap<>(); scoreMap.put(new Student("001", "张三"), 90); scoreMap.put(new Student("001", "张三"), 95); // 覆盖原有值(equals 返回 true) System.out.println(scoreMap.size()); // 输出 1| 维度 | Map | Collection |
|---|---|---|
| 存储形式 | 键值对(双列) | 单个元素(单列) |
| 核心子接口 | HashMap、TreeMap、ConcurrentHashMap 等 | List、Set、Queue 等 |
| 元素唯一性 | 键唯一,值可重复 | Set 元素唯一,List 元素可重复 |
| 遍历方式 | 键遍历、键值对遍历、值遍历 | 直接遍历、迭代器遍历 |
| 核心方法 | put、get、remove(按键操作) | add、remove、contains(按元素操作) |
accessOrder = true让访问过的元素移到链表尾部,淘汰链表头部元素。Map 是 Java 中处理键值对映射的核心工具,不同实现类适配不同场景:
HashMap;LinkedHashMap;TreeMap;ConcurrentHashMap;Hashtable(性能差、API 老旧)。掌握 Map 的底层原理和使用规范,是优化 Java 程序性能、避免并发问题的关键。