Java集合框架

Java集合框架 🔥 结构化

核心定位:Java集合框架是存储/管理/操作一组数据的容器体系,替代原生数组的短板,提供动态扩容、增删改查、排序、筛选等丰富功能,是开发必备、面试高频的核心知识点。

一、集合框架核心概述

✅ 核心定义与优势

集合:Java提供的容器类,用于存储多个对象(基本数据类型会自动装箱为包装类)。

对比数组的核心优势:

✅ 长度动态可变,无需初始化指定长度;

✅ 内置海量API,支持增删改查、排序、去重、遍历等操作;

✅ 支持泛型,编译期校验数据类型,避免类型转换异常;

✅ 体系完善,可根据业务场景(有序/无序、可重复/不可重复、键值对)灵活选型。

✅ 整体体系结构(必背|脑图级清晰)

Java集合框架的顶层分为两大核心接口,所有集合类均基于这两个接口实现,无继承关系。

  1. 单列集合「Collection」------ 存储单个元素

核心特征:每个位置仅存放一个元素,是最基础的集合类型

Collection 【顶层接口】

├─ List 【子接口】:有序、可重复、有索引,支持按索引操作

│ ├─ ArrayList(数组实现):开发首选、查询快、增删慢

│ ├─ LinkedList(双向链表实现):增删快、查询慢,适配首尾操作场景

│ └─ Vector(数组实现):线程安全、效率极低,几乎弃用

└─ Set 【子接口】:无序、不可重复、无索引,核心作用是去重

├─ HashSet(哈希表实现):去重首选、效率最高,底层依赖HashMap

│ └─ LinkedHashSet:有序HashSet,记录元素插入顺序

└─ TreeSet(红黑树实现):自动排序,需实现Comparable接口

  1. 双列集合「Map」------ 存储键值对<K,V>

核心特征:以「键(Key)+值(Value)」形式存储,键唯一、值可重复,通过键快速查找值,开发高频使用

Map 【顶层接口】

├─ HashMap(哈希表实现):键值对首选、无序、效率最高、线程不安全

│ └─ LinkedHashMap:有序HashMap,记录键值对插入顺序

├─ TreeMap(红黑树实现):按键自动排序

└─ Hashtable(哈希表实现):线程安全、效率极低,几乎弃用

✅ 核心工具类

java.util.Collections:集合的工具类,提供静态方法实现集合的排序、反转、线程安全包装、查找最值等操作(注意区分:Collection是接口,Collections是工具类)。

二、核心集合类精讲(实战+源码级要点)

✅ 1. ArrayList(List核心|开发使用率95%+)

✔️ 底层实现

JDK全版本基于动态数组实现,默认初始容量10,扩容规则为原容量1.5倍。

✔️ 核心特点

✅ 查询/修改快(数组下标访问,时间复杂度O(1));

✅ 新增/删除慢(需移动数组元素,时间复杂度O(n));

✅ 有序、可重复、有索引;

✅ 非线程安全,效率高。

✔️ 实战代码(高频操作)

import java.util.ArrayList;

import java.util.List;

public class ArrayListDemo {

public static void main(String[] args) {

// 1. 创建对象(泛型限定类型,接口引用指向实现类 → 多态)

List<String> list = new ArrayList<>();

// 2. 核心操作:增、删、改、查

list.add("Java"); // 新增元素

list.add("MySQL");

list.add("Java"); // 允许重复

list.remove(0); // 按索引删除

list.set(0, "Redis");// 按索引修改

String val = list.get(0); // 按索引查询

// 3. 三种遍历方式(开发必会)

// 方式1:增强for(推荐,简洁)

for (String s : list) {

System.out.println(s);

}

}

}

✅ 2. LinkedList(List分支|适配高频增删场景)

✔️ 底层实现

基于双向链表实现,无数组扩容概念,每个节点存储元素+前驱/后继节点地址。

✔️ 核心特点

✅ 新增/删除快(仅需修改节点引用,时间复杂度O(1));

✅ 查询/修改慢(需遍历链表,时间复杂度O(n));

✅ 支持队列/栈的API(addFirst()/addLast()/pop()),适配首尾操作场景;

✅ 非线程安全。

✔️ 核心场景

频繁对集合首尾元素进行增删操作(如消息队列、任务栈)。

✅ 3. HashSet(Set核心|去重首选)

✔️ 底层实现

底层依赖HashMap:将元素作为HashMap的Key,Value固定为一个空对象PRESENT,利用HashMap的键唯一性实现去重。

✔️ 核心特点

✅ 无序、不可重复、无索引;

✅ 去重效率极高,时间复杂度O(1);

✅ 存储自定义对象时,必须重写hashCode()和equals(),否则无法实现去重。

✔️ 实战代码

import java.util.HashSet;

import java.util.Set;

public class HashSetDemo {

public static void main(String[] args) {

Set<Integer> set = new HashSet<>();

set.add(1);

set.add(2);

set.add(1); // 重复元素,自动去重

System.out.println(set); // 输出:[1,2]

}

}

✅ 4. HashMap(Map核心|键值对首选)

✔️ 底层实现(面试必考)

• JDK7:数组 + 链表;

• JDK8及以后:数组 + 链表 + 红黑树(当链表长度≥8、数组容量≥64时,链表转红黑树,查询效率从O(n)→O(logn))。

✔️ 核心特点

✅ 键唯一、值可重复,键为null仅允许1个,值为null无限制;

✅ 无序、非线程安全、效率最高;

✅ 默认初始容量16,负载因子0.75,扩容规则为原容量2倍。

✔️ 实战代码(高频操作)

import java.util.HashMap;

import java.util.Map;

public class HashMapDemo {

public static void main(String[] args) {

Map<String, Integer> map = new HashMap<>();

// 增:存键值对

map.put("Java", 90);

map.put("MySQL", 85);

// 查:按键取值

int score = map.get("Java");

// 删:按键删除

map.remove("MySQL");

// 遍历:键值对遍历(推荐)

for (Map.Entry<String, Integer> entry : map.entrySet()) {

System.out.println("键:" + entry.getKey() + ",值:" + entry.getValue());

}

}

}

三、高频核心对比(面试必考|易混点梳理)

✅ 1. List vs Set

维度 List Set

有序性 有序(按插入顺序) 无序(HashSet)/有序(LinkedHashSet/TreeSet)

重复性 允许重复 不允许重复

索引 有索引,支持下标操作 无索引,无法通过下标访问

核心方法 get(int index)、set(int index) 无索引相关方法,核心是add()去重

✅ 2. ArrayList vs LinkedList

维度 ArrayList LinkedList

底层结构 动态数组 双向链表

读写效率 查询O(1)、增删O(n) 增删O(1)、查询O(n)

内存占用 连续内存,占用少 节点存储额外引用,占用多

核心场景 查多改少(如数据展示) 增删多查少(如消息队列)

✅ 3. HashMap vs Hashtable

维度 HashMap Hashtable

线程安全 非线程安全,效率高 线程安全,效率极低

空值支持 键允许1个null,值允许多个null 键/值均不允许null

初始容量 16,扩容2倍 11,扩容2n+1

开发选型 开发首选(线程安全场景用ConcurrentHashMap) 完全弃用

✅ 4. HashSet vs TreeSet

维度 HashSet TreeSet

底层实现 哈希表(HashMap) 红黑树

有序性 无序 自动升序排列

去重规则 重写hashCode()+equals() 实现Comparable接口(重写compareTo())

效率 高(O(1)) 较低(O(logn))

四、集合核心考点(源码+面试级)

✅ 1. 泛型(集合标配|必用)

• 语法:ArrayList<String> list,限定集合只能存储指定类型的元素;

• 核心作用:编译期类型校验,避免运行时ClassCastException,无需手动强制类型转换;

• 本质:编译期语法糖,编译后泛型会被擦除,底层仍为Object类型。

✅ 2. HashSet如何保证元素不可重复?(面试高频)

  1. 当向HashSet添加元素时,先调用元素的hashCode()计算哈希值,确定元素在数组中的存储位置;

  2. 若该位置无元素,直接存入;若有元素,调用equals()比较两个元素是否相等;

  3. ✅ equals返回true → 视为重复元素,拒绝添加;

  4. ✅ equals返回false → 哈希冲突,以链表/红黑树形式挂载在该位置。

结论:存储自定义对象时,必须同时重写hashCode()和equals(),否则无法实现去重。

✅ 3. HashMap的扩容机制(源码级)

  1. 默认初始容量16,负载因子0.75,阈值=容量×负载因子(默认12);

  2. 当集合中元素数量≥阈值时,触发扩容,扩容后容量为原容量2倍;

  3. 扩容时会新建数组,将原数组的元素重新计算哈希值,迁移至新数组(哈希重排)。

✅ 4. 集合的线程安全问题

• 基础集合(ArrayList/HashSet/HashMap)均非线程安全,多线程环境下会出现并发修改异常(ConcurrentModificationException);

• 解决方案:

✅ 方案1:使用Collections.synchronizedXXX()工具类包装(如Collections.synchronizedList(new ArrayList<>()));

✅ 方案2:使用JUC并发集合(如CopyOnWriteArrayList、ConcurrentHashMap),效率更高,开发首选。

✅ 5. 集合遍历方式(开发必会)

✔️ 单列集合遍历(List/Set)

  1. 增强for循环(推荐,简洁);

  2. 迭代器Iterator(支持遍历中删除元素,避免并发修改异常);

  3. List专属:普通for循环(按索引遍历)。

✔️ 双列集合遍历(Map)

  1. 键值对遍历entrySet()(推荐,效率最高);

  2. 按键遍历keySet() + get(key)(效率低,二次查询);

  3. 按值遍历values()(仅需获取值时使用)。

五、高频面试题汇总(分基础/进阶)

✅ 基础必问(入行级)

  1. Java集合框架的两大顶层接口是什么?各自的特点?

  2. ArrayList和LinkedList的区别及使用场景?

  3. HashSet和TreeSet的区别?HashSet如何保证元素不可重复?

  4. HashMap的键和值有什么限制?

  5. Collection和Collections的区别?

✅ 进阶常考(面试级)

  1. HashMap的底层实现?JDK8做了哪些优化?

  2. HashMap的哈希冲突如何解决?为什么链表转红黑树的阈值是8?

  3. 为什么HashMap的初始容量是16,且必须是2的幂次?

  4. 集合遍历中出现ConcurrentModificationException的原因及解决方案?

  5. 如何实现集合的排序?(List用Collections.sort()、TreeSet/TreeMap实现Comparable接口)

六、核心总结(速记|考点提炼)

  1. 集合框架分为Collection(单列) 和Map(双列) 两大体系,核心是「接口+实现类」的多态设计;

  2. ArrayList 是开发首选集合,HashMap 是开发首选键值对容器,HashSet 是去重首选;

  3. 集合的核心痛点:泛型限定类型、去重规则、线程安全、遍历方式;

  4. 集合的设计思想完美体现Java面向对象的封装、多态,是OOP思想的落地典范。

相关推荐
梦想的旅途22 小时前
企业微信外部群消息推送实战指南
java·golang·企业微信
独自破碎E2 小时前
怎么实现一个滑动验证码功能?又如何防止被机器识别破解
java·spring boot·后端
lbb 小魔仙3 小时前
【Java】Spring Data JPA 详解:ORM 映射、查询方法与复杂 SQL 处理
java·开发语言·sql·spring cloud
倚肆3 小时前
Kafka部署指南:单机开发模式与集群生产模式( 4.1.1 版本)
java·分布式·kafka
qq13267029403 小时前
ARM版统信UOS桌面安装JDK
java·jdk·arm·统信uos·毕昇jdk 11
码头工人3 小时前
【架构师系列】风控场景下超高并发频次计算服务的设计与实践
java·架构·风控·反爬
长不大的蜡笔小新3 小时前
私人健身房管理系统
java·javascript·spring boot
hdsoft_huge4 小时前
Java 实现高效查询海量 geometry 及 Protobuf 序列化与天地图前端分片加载
java·前端·状态模式
xiaowu0804 小时前
IEnumerable、IEnumerator接口与yield return关键字的相关知识
java·开发语言·算法