【Java】集合面试全套精讲|HashMap/ArrayList高频考点完整版
大家好我是程序员二叉。简介本文整理Java面试高频集合核心考点聚焦HashMap、ArrayList、HashSet、Tree系列、LinkedHashMap等常用容器梳理底层结构、扩容逻辑、存取流程、哈希冲突、线程安全、排序机制、容器差异对比等重难点区分JDK7与JDK8 HashMap关键改动清晰对比各类容器适用场景可直接用于面试背诵与技术笔记查阅。欢迎点赞收藏关注。一、HashMap 基础参数 扩容机制1. 默认值默认容量16必须是 2 的 n 次方默认负载因子0.75扩容倍数2 倍newCap oldCap 12. 扩容机制当元素数量 容量 × 负载因子时触发扩容扩容 创建新的 2 倍容量数组重新计算所有元素的哈希位置迁移到新数组JDK8 迁移时保持链表顺序避免死循环二、HashMap put () 完整执行流程JDK8首次 put数组未初始化先延迟初始化容量为 16计算 key 的hash 值再计算数组下标i (n - 1) hash若该位置无元素直接插入若该位置是链表遍历链表equals 对比 key找到则覆盖 value没找到则尾插法插入链表长度 ≥ 8且数组容量 ≥ 64→ 转为红黑树若该位置是红黑树按树结构插入或更新插入完成后判断是否需要扩容需要则扩容三、HashMap get () 完整执行流程计算 key 的 hash定位数组下标数组位置无节点→ 返回null第一个节点 key 匹配 → 直接返回 value若是红黑树→ 树查找若是链表→ 遍历链表 equals 匹配找不到 → 返回null四、HashMap 如何解决哈希冲突JDK7数组 链表 头插法JDK8数组 链表 红黑树 尾插法冲突解决策略相同下标时用链表存储链表过长会影响查询JDK8 升级为红黑树红黑树节点变少后会退化为链表五、HashMap 为什么线程不安全1. JDK7头插法 → 死循环扩容时链表逆序多线程下形成环形链表get()时无限循环。2. JDK8尾插法解决死循环但仍不安全多线程同时 put 会数据覆盖size 计数不准确扩容期间数据丢失结论HashMap 无锁设计任何多线程场景都不能用。六、头插法 vs 尾插法 缺点1. 头插法JDK7优点插入快致命缺点多线程扩容死循环2. 尾插法JDK8优点无死循环缺点依然线程不安全会出现数据覆盖七、HashMap 和 Hashtable 区别线程安全HashMap 不安全Hashtable 安全全方法 synchronizednull 值HashMap 允许 1 个 null key 多个 null valueHashtable 不允许 null效率HashMap 快Hashtable 极慢扩容HashMap 2 倍Hashtable 2 倍 1底层结构HashMap JDK8 有红黑树Hashtable 永远链表推荐不用 Hashtable多线程用 ConcurrentHashMap八、负载因子为什么是 0.75官方选择空间成本 查询效率的最优平衡0.75空间浪费冲突少0.75冲突剧增链表变长查询变慢0.75 是数学统计最优值九、链表转红黑树阈值 8 / 6 原理1. 树化阈值8根据泊松分布哈希冲突达到 8 的概率极低千万分之一正常情况下几乎不会树化避免红黑树浪费内存。2. 退化为链表6不使用 7 是为了防止频繁在树和链表之间反复切换抖动。十、为什么不直接用红黑树红黑树内存占用是链表的 2 倍以上链表长度短的时候查询速度不比树慢只有冲突严重时才需要树来优化 O (n) → O (logn)设计思想用最小内存满足绝大多数场景。十一、ArrayList vs LinkedList 底层 性能1. 底层ArrayList动态数组LinkedList双向链表2. 性能对比查询ArrayList 快O (1)LinkedList 慢O (n)尾部增删ArrayList 快LinkedList 一般中间 / 头部增删ArrayList 慢拷贝数组LinkedList 快O (1)内存ArrayList 紧凑LinkedList 节点开销大3. 开发建议99% 场景用 ArrayListLinkedList 极少使用。十二、ArrayList 扩容机制默认容量0首次添加才扩容为 10扩容条件元素数量达到数组长度新容量 旧容量× 1.5底层使用Arrays.copyOf复制数组十三、HashSet 如何保证不重复底层是什么1. 底层基于 HashMap 实现value 存固定的new Object()。2. 不重复原理add 元素 map.put (e, PRESENT)key 唯一 元素唯一判断重复hashCode() equals()hashCode 不同 → 一定不重复hashCode 相同 → 再用 equals 确认十四、HashMap vs TreeMap有序性HashMap 无序TreeMap有序自然排序 / 定制排序底层HashMap 数组 链表 红黑树TreeMap红黑树key 要求HashMap key 可 nullTreeMap key 不能 null性能HashMap 增删查更快TreeMap 适合排序场景十五、LinkedHashMap 有序性如何实现内部维护双向链表插入元素时同步维护链表前后指向遍历按插入顺序输出支持访问顺序LRU 缓存十六、TreeSet 排序原理 Comparable vs Comparator1. TreeSet 排序原理底层 TreeMap基于红黑树自动排序。2. Comparable内部比较器类自身实现implements Comparable重写compareTo()定义默认排序规则3. Comparator外部比较器单独编写比较器类重写compare()不修改原类灵活定制排序4. 区别Comparable自身比较一个规则Comparator外部比较多个规则解耦总结面试必背HashMap 默认容量 16、负载因子 0.75、扩容 2 倍JDK8 结构数组 链表 红黑树尾插法无线程死循环线程不安全原因JDK7 死循环、JDK8 数据覆盖HashSet 底层就是 HashMap靠 key 保证唯一ArrayList 数组、LinkedList 链表优先用 ArrayListTree 系列靠红黑树排序Comparable 是自身Comparator 是外部