【Java零基础连载12】Java集合框架下篇|HashSet、LinkedHashSet、HashMap、LinkedHashMap底层原理与面试详解
✨ 专栏Java零基础全套入门连载教程 简介本文承接上篇List有序集合内容彻底收官Java集合框架全套体系。重点精讲无序、去重系列核心集合单列Set集合HashSet、LinkedHashSet、双列Map集合HashMap、LinkedHashMap。从零吃透哈希表底层结构、元素去重原理、存取机制、扩容规则、哈希冲突解决方案详解JDK1.7与JDK1.8 HashMap核心差异、红黑树转换条件、线程不安全坑点。搭配海量实战代码、底层源码解析、性能对比、场景选型、面试真题零基础彻底拿捏Java集合最高频、最难、面试必考的哈希集合体系。 标签Java集合,HashMap,HashSet,LinkedHashMap,LinkedHashSet,哈希表底层,Java面试,Java零基础一、前言上一篇我们彻底搞定了List系列有序集合吃透了ArrayList动态数组、LinkedList双向链表、Vector底层原理与业务选型逻辑掌握了日常开发有序数据存储的全部方案。本篇我们攻克Java集合框架终极重难点、面试天花板——哈希集合体系包含单列Set集合与双列Map集合。如果说List是业务常用基础那么HashMap就是Java集合的核心王者是面试必问、底层最深、坑点最多、框架底层依赖最强的集合。Spring、MyBatis、Redis、缓存机制底层全部依托哈希表思想实现。很多开发者工作多年依然搞不懂元素如何去重、哈希冲突怎么解决、为什么会转红黑树、JDK1.8做了哪些优化、LinkedHashMap有序原理。本篇一次性零基础讲透无死角吃透哈希集合全套知识点完结Java集合所有核心内容读完本篇你将彻底掌握Set集合核心特性、无序不可重复原理与适用场景HashSet底层依托HashMap实现、元素去重完整机制LinkedHashSet有序特性、底层链表结构与差异化优势Map集合核心特性、key-value存储原理与通用方法HashMap哈希表底层、数组链表红黑树完整结构HashMap扩容机制、哈希冲突解决、树化阈值规则JDK1.7与JDK1.8 HashMap核心差异与优化点LinkedHashMap有序原理、LRU缓存实现思想全套哈希集合性能对比、业务选型、高频面试坑点二、Set集合核心总览Set是单列无序集合是Collection的核心子接口和List完全对立解决数据去重、无序存储的业务场景。2.1 Set集合三大核心特性无序存储顺序与取出顺序不一致无固定排序逻辑不可重复自带去重机制无法存储重复元素无索引没有下标无法通过索引获取、修改元素只能遍历获取2.2 Set常用实现类HashSet底层哈希表无序去重查询存取效率最高常用LinkedHashSet哈希表双向链表保留插入顺序有序去重TreeSet底层红黑树自带自然排序可自定义规则排序三、HashSet底层原理与实战HashSet是Set集合最常用实现类底层完全依托HashMap实现所有去重、存取逻辑都是哈希表机制性能极高。3.1 核心特性底层结构哈希表数组链表红黑树无序、不可重复、无索引存取速度极快增删查时间复杂度接近O(1)线程不安全多线程并发需手动同步3.2 元素去重核心原理面试必考HashSet实现去重依赖hashCode() equals()双重校验机制新增元素时先调用对象hashCode()计算哈希值确定数组存储位置若该位置无元素直接存入无重复问题若该位置已有元素调用equals()逐一对内容比较equals返回true判定为重复元素舍弃不存储equals返回false判定为哈希冲突挂载链表/树节点存储核心结论自定义对象去重必须重写 hashCode() 和 equals() 方法否则默认使用地址值比较无法实现内容去重3.3 HashSet实战代码import java.util.HashSet; public class HashSetDemo { public static void main(String[] args) { HashSetString set new HashSet(); // 添加元素自动去重 set.add(Java); set.add(Python); set.add(Java); set.add(Go); // 无序输出、无重复数据 System.out.println(set); // 判断元素是否存在 System.out.println(set.contains(Java)); // 删除元素 set.remove(Python); // 遍历集合 for (String s : set) { System.out.println(s); } } }四、LinkedHashSet有序去重集合LinkedHashSet是HashSet的子类在哈希表基础上新增双向链表解决HashSet无序的问题实现有序去重双重特性。4.1 核心特性底层结构哈希表 双向链表保留插入顺序存取顺序一致自带去重机制不可存储重复元素性能略低于HashSet有序去重场景首选4.2 实战演示有序去重import java.util.LinkedHashSet; public class LinkedHashSetDemo { public static void main(String[] args) { LinkedHashSetInteger set new LinkedHashSet(); set.add(5); set.add(1); set.add(3); set.add(1); // 重复元素自动去重 // 输出顺序与插入顺序一致且无重复 System.out.println(set); } }4.3 Set集合选型总结只去重、不要求有序首选 HashSet性能最高去重且保留插入顺序首选 LinkedHashSet去重且需要自然排序使用 TreeSet五、Map集合核心总览Map是Java双列集合顶层接口区别于Collection单列集合以Key-Value键值对形式存储数据是全局最核心、使用频率最高的存储结构。5.1 Map核心特性键值对存储一个Key对应一个ValueKey唯一、不可重复Value可重复无序、无索引Key可为null仅允许一个null键Value可多个null5.2 Map常用实现类HashMap底层哈希表无序存取性能极高开发首选LinkedHashMap哈希表链表保留插入顺序TreeMap底层红黑树按键自动排序HashTable古老线程安全集合效率低、基本废弃5.3 Map通用核心方法// 添加/修改键值对 put(K key, V value); // 根据key获取value get(Object key); // 根据key删除键值对 remove(Object key); // 判断是否包含指定key containsKey(Object key); // 判断是否包含指定value containsValue(Object value); // 获取所有key集合 keySet(); // 获取所有value集合 values(); // 获取键值对集合遍历核心 entrySet(); // 获取集合键值对个数 size(); // 清空集合 clear();六、HashMap底层超详细解析面试核心HashMap是Java集合的重中之重底层哈希表结构JDK1.8做了史诗级优化是面试必考压轴题下面从零拆解全套底层原理。6.1 底层存储结构JDK1.8数组 链表 红黑树三合一结构完美平衡查询与增删性能数组主体存储结构快速定位索引位置链表解决少量哈希冲突挂载冲突元素红黑树解决链表过长查询变慢问题平衡树查询效率O(logn)6.2 核心参数必须熟记默认初始容量16最大容量2^30负载因子0.75扩容阈值系数扩容阈值容量 * 负载因子 12元素达到12个触发扩容树化阈值链表长度 8 且 数组容量 64链表转红黑树链化阈值红黑树节点 6树转回链表6.3 HashMap存取流程调用put方法存入key-value通过key计算哈希值通过哈希值 数组长度-1 计算数组索引位置索引位置为空直接新建节点存入数据索引位置不为空比较key哈希值与内容key完全一致覆盖原有value值key不一致产生哈希冲突向后挂载链表节点链表长度达到8、数组容量达到64链表树化为红黑树元素数量超过扩容阈值数组自动扩容为原来2倍6.4 JDK1.7 VS JDK1.8 核心差异高频面试对比维度JDK1.7JDK1.8底层结构数组单向链表数组链表红黑树插入方式头插法易造成循环链表死循环尾插法规避死循环问题初始化机制创建对象直接初始化容量16懒加载首次put才初始化节省内存冲突优化链表过长性能严重下降树化优化查询性能大幅提升6.5 HashMap实战代码import java.util.HashMap; import java.util.Map; public class HashMapDemo { public static void main(String[] args) { HashMapString, Integer map new HashMap(); // 添加键值对 map.put(Java, 99); map.put(Python, 88); map.put(Java, 100); // key重复覆盖value // 根据key取值 System.out.println(Java分数 map.get(Java)); // 判断key是否存在 System.out.println(map.containsKey(Python)); // 遍历Map for (Map.EntryString, Integer entry : map.entrySet()) { System.out.println(entry.getKey() : entry.getValue()); } } }6.6 HashMap核心坑点总结线程不安全多线程put、扩容会出现数据覆盖、丢失、死循环问题并发场景禁用自定义对象作为Key必须重写hashCode和equals方法负载因子0.75是时间与空间最优平衡不建议手动修改链表树化必须同时满足两个条件链表长度≥8、数组容量≥64key重复会直接覆盖value不会报错七、LinkedHashMap有序Map集合LinkedHashMap是HashMap的子类底层在哈希表基础上新增双向链表保留元素插入顺序完美解决HashMap无序问题。7.1 核心特性底层结构哈希表 双向链表有序、key唯一、value可重复默认保留插入顺序可开启访问顺序排序性能略低于HashMap有序键值对场景首选7.2 LRU缓存实现思想面试拓展LinkedHashMap自带访问排序机制重写removeEldestEntry方法可快速实现LRU最近最少使用缓存淘汰策略是简易本地缓存的经典实现方式。7.3 实战演示import java.util.LinkedHashMap; public class LinkedHashMapDemo { public static void main(String[] args) { LinkedHashMapString, Integer map new LinkedHashMap(); map.put(张三, 20); map.put(李四, 22); map.put(王五, 21); // 输出顺序与插入顺序完全一致 System.out.println(map); } }八、集合全套终极选型指南开发直接用8.1 单列集合Collection选型有序可重复、查询多增删少ArrayList首选有序可重复、频繁首尾增删LinkedList无序去重、追求高性能HashSet有序去重LinkedHashSet排序去重TreeSet8.2 双列集合Map选型无序键值对、高性能存取HashMap90%业务首选有序键值对LinkedHashMap按键排序TreeMap多线程安全MapConcurrentHashMapJUC并发篇详解九、本篇总结本篇彻底收官Java集合框架全套体系攻克Java进阶核心重难点掌握面试与开发核心能力精通Set集合无序去重特性掌握HashSet、LinkedHashSet底层原理与选型吃透hashCodeequals双重去重机制解决自定义对象去重痛点掌握Map键值对存储核心特性、通用操作方法与遍历方式深度拿捏HashMap数组链表红黑树底层、扩容、树化、哈希冲突机制熟记JDK1.7与1.8 HashMap核心优化与差异、高频面试考点掌握LinkedHashMap有序原理与LRU缓存思想形成完整集合选型思维适配所有日常业务场景至此Java零基础全套集合框架彻底完结从List有序集合到Set、Map哈希集合从底层结构到实战选型、面试坑点全覆盖无死角完全满足初级开发与面试需求。十、下期预告下一篇Java泛型详解泛型原理、通配符、上下限、泛型类/方法/接口实战解锁Java类型安全高级特性透彻讲解泛型诞生意义、擦除机制、通配符使用、上下限约束结合集合泛型实战解决类型转换异常、代码复用问题为后续框架、源码学习筑牢核心基础持续更新Java零基础全套连载关注专栏从零学Java稳步进阶后端开发