当前位置: 首页 > article >正文

Java 集合框架核心知识点全解析:从入门到高频面试题(含 JDK 源码剖析)

一、Java 集合框架体系架构

Java 集合框架分为两大分支:

  1. Collection接口:存储单个元素,包括:
    • List:有序、可重复(如ArrayListLinkedList
    • Set:无序、唯一(如HashSetTreeSet
    • Queue:队列(如PriorityQueueLinkedBlockingQueue
  2. Map接口:存储键值对(如HashMapConcurrentHashMap

核心设计思想

  • 接口层定义操作规范(如add()get()
  • 实现层提供不同数据结构的具体实现
  • 工具层CollectionsArrays)提供排序、同步等辅助方法

二、核心接口与实现类深度解析

2.1 List 家族:有序数据的存储方案

2.1.1 ArrayList 源码剖析
  • 底层实现:基于动态数组(Object[] elementData),支持随机访问
  • 扩容机制
    • 初始容量为10(JDK1.8 后),扩容时按1.5 倍增长
    • 源码核心逻辑:
      int newCapacity = oldCapacity + (oldCapacity >> 1); // 1.5倍扩容
      elementData = Arrays.copyOf(elementData, newCapacity); // 数组复制
      
  • 适用场景:适合高频随机访问(如get(index)),不适合频繁中间插入 / 删除
2.1.2 LinkedList 双向链表实现
  • 数据结构:双向链表,每个节点包含prevnext指针
  • 核心优势
    • 头尾操作高效(addFirst()removeLast()均为 O (1))
    • 无需连续内存,适合频繁增删场景
  • 缺点:随机访问需遍历链表(get(index)为 O (n))

2.2 Set 家族:唯一性与排序策略

2.2.1 HashSet 存储原理
  • 唯一性实现
    1. 通过hashCode()计算元素哈希值,确定存储桶位置
    2. 在桶内通过equals()方法对比元素是否重复
  • JDK8 优化
    • 当链表长度≥8 且数组长度≥64 时,链表转为红黑树(提升查询效率至 O (log n))
  • 注意:若自定义类存入HashSet,需重写hashCode()equals()方法
2.2.2 TreeSet 排序规则
  • 自然排序:元素需实现Comparable接口(如IntegerString
  • 定制排序:通过Comparator接口指定排序规则
    // 降序排列整数
    TreeSet<Integer> ts = new TreeSet<>(Comparator.reverseOrder());
    

2.3 Map 家族:键值对的高效检索

2.3.1 HashMap 线程不安全问题
  • 多线程风险
    • JDK7 中采用头插法扩容,多线程下可能形成循环链表,导致死锁
    • JDK8 改为尾插法,但仍不保证线程安全
  • 解决方案
    • 使用ConcurrentHashMap(推荐)
    • 通过Collections.synchronizedMap()包装(全表锁,性能较低)
2.3.2 ConcurrentHashMap 的锁优化
  • JDK7:分段锁(Segment数组,默认 16 个分段,并发度 16)
  • JDK8
    • 采用CAS+synchronized锁定单个节点(锁粒度更细)
    • 链表转红黑树优化查询效率
    // JDK8 put操作关键代码
    synchronized (f) { // 锁定当前桶的头节点if (f.hash == hash && f.key == key) {// 处理键存在的情况}
    }
    

三、高频面试题与最佳实践

3.1 集合选型对比表

需求场景优先选择时间复杂度线程安全
高频随机访问ArrayListO (1)(访问)
高频首尾增删LinkedListO (1)(首尾操作)
唯一无序集合HashSetO (1)(插入 / 查询)
有序键值对排序TreeMapO(log n)
高并发读写ConcurrentHashMapO (1)(平均)

3.2 性能优化实战

  1. 预分配容量
    // 避免ArrayList多次扩容
    List<String> list = new ArrayList<>(100); // 初始容量100
    // 避免HashMap频繁rehash
    Map<String, Integer> map = new HashMap<>(16); // 初始容量16(需满足初始数据量/负载因子)
    
  2. 遍历优化
    • ArrayList:普通for循环(直接通过下标访问)
    • LinkedList:使用ListIterator双向遍历
    • Map:优先使用entrySet()而非keySet()(减少键值对拆分开销)

四、JDK 新特性深度解读

4.1 Java8 Stream API 实战

// 案例:过滤长字符串并转大写
List<String> result = list.stream().filter(s -> s.length() > 3) // 过滤长度>3的元素.map(String::toUpperCase)    // 转大写.collect(Collectors.toList()); // 收集结果// 案例:按首字母分组统计
Map<Character, List<String>> groupMap = list.stream().collect(Collectors.groupingBy(s -> s.charAt(0)));

4.2 Java9 不可变集合工厂

// 创建不可变List(元素不可修改,不允许null)
List<String> immutableList = List.of("A", "B", "C"); 
// 创建不可变Map(键值均不可修改)
Map<String, Integer> map = Map.of("a", 1, "b", 2);

五、常见陷阱与避坑指南

5.1 并发修改异常(ConcurrentModificationException)

错误场景

List<String> list = new ArrayList<>();
list.add("1");
for (String s : list) { // 底层使用Iterator,modCount校验机制if (s.equals("1")) {list.remove(s); // 触发modCount不一致,抛出异常}
}

正确做法:使用迭代器的remove()方法

Iterator<String> it = list.iterator();
while (it.hasNext()) {String s = it.next();if (s.equals("1")) {it.remove(); // 安全删除}
}

5.2 哈希值与相等性陷阱

// 自定义类未重写hashCode/equals的后果
class User {private String id;// 未重写hashCode和equals
}Set<User> set = new HashSet<>();
set.add(new User("1"));
System.out.println(set.contains(new User("1"))); // 输出false(哈希值不同)

解决方案

@Override
public int hashCode() {return Objects.hash(id);
}@Override
public boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;User user = (User) o;return Objects.equals(id, user.id);
}

六、总结与学习路线

6.1 核心知识图谱

  • 数据结构:数组、链表、哈希表、红黑树的应用场景
  • 线程安全Vector/HashTable的缺陷,ConcurrentHashMap的锁优化
  • 性能优化:容量预分配、遍历方式选择、哈希函数设计

6.2 学习建议

  1. 源码精读:优先阅读ArrayListHashMapConcurrentHashMap的源码
  2. 工具辅助:使用Java VisualVM分析集合内存占用,JMH进行性能基准测试
  3. 算法实践:通过 LeetCode 题目(如两数之和、字母异位词分组)强化集合应用

本文涵盖 Java 集合框架的核心原理、面试高频考点及实战优化,建议收藏并结合源码练习加深理解。如有疑问,欢迎在评论区留言讨论! 🚀

相关文章:

Java 集合框架核心知识点全解析:从入门到高频面试题(含 JDK 源码剖析)

一、Java 集合框架体系架构 Java 集合框架分为两大分支&#xff1a; Collection接口&#xff1a;存储单个元素&#xff0c;包括&#xff1a; List&#xff1a;有序、可重复&#xff08;如ArrayList、LinkedList&#xff09;Set&#xff1a;无序、唯一&#xff08;如HashSet、…...

一文详解生成式 AI:李宏毅《生成式 AI 导论》学习笔记

生成式 AI 是怎么回事 人工智能&#xff08;Artificial Intelligence&#xff09; “智能”是一个广泛而复杂的概念&#xff0c;其定义和应用范围随着技术、科学和社会的发展不断演变。在当前的语境下&#xff0c;“智能”通常与人工智能&#xff08;AI&#xff09;相关联&am…...

什么是物联网 (IoT):2024 年物联网概述

物联网&#xff08;IoT&#xff09;是一个有望彻底改变我们生活、工作以及与环境互动方式的概念。如今&#xff0c;越来越多的新兴企业和老牌企业都在利用物联网的力量创造创新产品与服务。正因为这一转变&#xff0c;互联互通已成为我们生活中不可或缺的一部分&#xff0c;科技…...

8级-数组

前情回顾&#xff1a;在7级的时候&#xff0c;我们学习了如何定义、使用函数 目录 概念 什么是数组&#xff1f; 一维数组 声明 初始化 访问元素 计算数组长度 二维数组 声明 初始化 访问元素 思考 一维数组在内存中如何存储&#xff1f; 二维数组在内存中如何存储&…...

大模型 Agent 就是文字艺术吗?

最近在技术圈里有一个很有趣的争论&#xff1a;大模型 Agent 是不是就是各种 Prompt 的堆叠&#xff1f;像 Manus 这样看起来很智能的 Agent&#xff0c;本质上是不是就是用巧妙的 Prompt 约束大模型生成更好的输出&#xff1f;换句话说&#xff0c;这是不是一门文字艺术&#…...

YOLOv8检测头代码详解(示例展示数据变换过程)

本文旨在通过实例数据&#xff0c;详细解读YOLOv8检测头的网络结构及其代码实现。首先将从检测头的网络架构开始讲解&#xff0c;涵盖代码与网络结构图的对比分析。关键在于深入探讨检测头的输出结果&#xff0c;因为这些输出将直接用于损失函数的计算。由于在不同阶段&#xf…...

JUC并发编程1

什么是juc 在java的java.util.concurrent包下的工具。 锁 传统的synchronize public class SealTicket {int total 50;public synchronized void seal() {if (total > 0) {System.out.println(Thread.currentThread().getName() "卖出第" (total--) "张…...

消息队列RabbitMQ与AMQP协议详解

消息队列RabbitMQ与AMQP协议详解 什么是RabbitMQ RabbitMQ是一个开源的消息队列中间件&#xff0c;基于AMQP&#xff08;Advanced Message Queuing Protocol&#xff09;协议实现。它作为一个消息代理&#xff08;Message Broker&#xff09;&#xff0c;可以接收、存储和转发…...

Day 29 训练

Day 29 训练 Day 29&#xff1a;Python 类装饰器的奥秘与实践一、类装饰器&#xff1a;函数装饰器的升级版二、类装饰器 VS 函数装饰器&#xff1a;核心区别三、实战&#xff1a;为类添加日志功能四、类方法定义的两种风格1. 类内部定义方法&#xff08;常规方式&#xff09;2.…...

STM32开发环境配置——VSCode+PlatformIO + CubeMX + FreeRTOS的集成环境配置

前言 为什么配置这样的一个环境呢&#xff1f;鄙人受够了Keil5那个简陋的工作环境了&#xff0c;实在是用不下去&#xff0c;调试上很容易跟CubeMX的代码产生不协调导致调试——发布代码不一致造成的一系列问题。CubeIDE虽说不错&#xff0c;但是它的代码辅助功能和构建系统实在…...

Profibus转Profinet网关赋能鼓式硫化机:智能化生产升级的关键突破

在现代工业自动化领域&#xff0c;通讯协议转换器发挥着至关重要的角色。它们能够实现不同网络间的无缝对接和数据传输&#xff0c;确保了生产线上的设备可以顺畅地交流信息。今天&#xff0c;我们就来深入讨论开疆智能profibus转profinet网关KJ-PBM-PN以及其在鼓式硫化机中的应…...

redis 缓存穿透,缓存雪崩,缓存击穿

之前也不知道是哪个老六总结出来得缓存穿透&#xff0c;缓存击穿 。 穿透&#xff0c;击穿 中文上容易搞混&#xff0c;所以贴出英文 缓存穿透: Cache Penetration “Penetration” 有穿透、渗透之意, eg: the penetration of hackers into the system (黑客对系统的侵入) 缓…...

JAVA8怎么使用9的List.of

在 Java 8 中&#xff0c;List.of 方法并不可用&#xff0c;因为这是从 Java 9 开始引入的用于创建不可变列表的便捷方法。要在 Java 8 中达到类似的效果&#xff0c;您需要使用其他方式来创建列表。常规的方法是先创建集合对象然后再添加元素 List<String> list new A…...

告别手动测试:AUTOSAR网络管理自动化测试实战

文章目录 一、自动化测试系统架构硬件组成软件架构 二、测试覆盖的关键场景状态机测试时间参数测试容错性测试 三、测试case举例四、小结 一、自动化测试系统架构 AUTOSAR网络管理自动化测试由硬件设备和软件工具共同完成。 硬件组成 程控电源&#xff08;DUT供电&#xff0…...

BUCK电路利用状态空间平均法和开关周期平均法推导

以BUCK电路为例的两种方法推导 BUCK电路简介 BUCK电路是一种降压型DC-DC转换器,其拓扑结构如下: 输入电压 V in V_{\text{in}} Vin​,输出电压 V out = D V in V_{\text{out}} = D V_{\text{in}} Vout​=DVin​(稳态时, D D D为占空比)。关键元件:开关管 S S S、续流…...

MongoDB 用户与权限管理完全指南

在当今数据驱动的时代&#xff0c;数据库安全已成为企业IT架构中最关键的环节之一。作为最受欢迎的NoSQL数据库之一&#xff0c;MongoDB提供了完善的用户认证和权限管理机制&#xff0c;但许多开发者和数据库管理员对这些功能的理解和应用仍停留在表面层次。本文将全面剖析Mong…...

C++滑动门问题(附两种方法)

题目如下&#xff1a; 滑动窗口 - 题目 - Liusers OJ ——引用自OJ网站 方法如下&#xff1a; 1.常规思想 #include<bits/stdc.h> using namespace std; int main() {int n,k;int a[110];cin>>n>>k;for(int i0;i<n;i){cin>>a[i];}for(int i0;i…...

基于ITcpServer/IHttpServer框架的HTTP服务器

https://www.cnblogs.com/MuZhangyong/p/16839231.html 在基于ITcpServer/IHttpServer框架的HTTP服务器实现中,OnBody方法主要用于接收HTTP请求体数据,而触发HTTP响应通常是在OnMessageComplete方法中完成。以下是完整的响应触发机制说明: sequenceDiagramClient->>…...

初识main函数

int main(int argc, char *argv[]) {int a 0;return a; }X64 MSVC编译器 Windows x64调用约定 { // 将第二个参数(rdx)保存到栈[rsp0x10]位置 0x7ff6e54c2ad0 mov qword ptr [rsp10h],rdx // 将第一个参数(ecx)保存到栈[rsp8]位置 0x7ff6e54c2ad5 …...

FPGA高效验证工具Solidify 8.0:全面重构图形用户界面

近日&#xff0c;FPGA高效验证工具Solidify发布了8.0版本。该版本对图形用户界面&#xff08;GUI&#xff09;进行了全面重构&#xff0c;历时两年&#xff0c;经过了大幅的架构改进&#xff0c;旨在为用户提供更安全、更稳定的使用环境。 Solidify的用户对隐私有严格要求&…...

SIL2/PLd 认证 Inxpect毫米波安全雷达:3D 扫描 + 微小运动检测守护工业安全

Inxpect 成立于意大利&#xff0c;专注工业安全技术。自成立起&#xff0c;便致力于借助先进雷达技术提升工业自动化安全标准&#xff0c;解决传统安全设备在复杂环境中的局限&#xff0c;推出获 SIL2/PLd 和 UL 认证的安全雷达产品。 Inxpect 的雷达传感器技术优势明显。相较于…...

java中string类型的list集合放到redis的5种数据类型的那种比较合适呢,可以用StringRedisTemplate实现

在Java中&#xff0c;如何将一个String类型的List集合存储到Redis中&#xff0c;并且应该选择Redis的哪种数据类型。同时&#xff0c;用户还问到是否可以使用StringRedisTemplate来实现。 首先&#xff0c;我需要回忆一下Redis的5种主要数据类型&#xff1a;字符串&#xff08;…...

PyQt学习系列09-应用程序打包与部署

PyQt学习系列笔记&#xff08;Python Qt框架&#xff09; 第九课&#xff1a;PyQt的应用程序打包与部署 课程目标 掌握使用 PyInstaller 将PyQt应用程序打包为独立可执行文件学习处理 资源文件&#xff08;图标、样式表、图片&#xff09;和 依赖项实现 跨平台部署&#xff0…...

实现图片自动压缩算法,canvas压缩图片方法

背景&#xff1a; 在使用某些支持webgl的图形库&#xff08;eg&#xff1a;PIXI.js&#xff0c;fabric.js&#xff09;场景中&#xff0c;如果加载的纹理超过webgl可处理的最大纹理限制&#xff0c;会导致渲染的纹理缺失&#xff0c;甚至无法显示。 方案 实现图片自动压缩算…...

《数据结构笔记三》:单链表(创建、插入、遍历、删除、释放内存等核心操作)

不带头节点的单链表&#xff1a;&#xff08;不带表头&#xff09; #include<stdio.h> #include<stdlib.h> #include<string.h> //定义一个链表节点结构体 typedef struct Node {/* data */int data; //表示节点数据域struct Node *next; //…...

光伏行业如何利用SD-WAN优化分布式网络:替代MPLS、VPN、4G/5G的网络架构升级与云安全方案全解析

光伏行业的网络通信挑战与SD-WAN技术方案对比分析 光伏行业的分布式网络架构、远程站点多、通信环境复杂&#xff0c;以及对实时数据传输的高要求&#xff0c;使得网络架构成为影响行业数字化转型的重要因素。近年来&#xff0c;SD-WAN&#xff08;软件定义广域网&#xff09;…...

2025电工杯数学建模A题思路数模AI提示词工程

我发布的智能体链接&#xff1a;数模AI扣子是新一代 AI 大模型智能体开发平台。整合了插件、长短期记忆、工作流、卡片等丰富能力&#xff0c;扣子能帮你低门槛、快速搭建个性化或具备商业价值的智能体&#xff0c;并发布到豆包、飞书等各个平台。https://www.coze.cn/search/n…...

LLM | 论文精读 | NAACL 2025 | Clarify When Necessary:教语言模型何时该“问一句”再答!

&#x1f50d; 解读 NAACL 2025 重磅论文《Clarify When Necessary》&#xff1a;教语言模型何时该“问一句”再答&#xff01; &#x1f9e9; 一、现实问题&#xff1a;大模型“看不懂装懂”有多危险&#xff1f; 我们每天用的 ChatGPT、Claude 等大型语言模型&#xff08;LL…...

嵌入式鸿蒙openharmony应用开发环境搭建与工程创建实现

各位小伙伴大家好,本周开始分享鸿蒙开发相关的内容,从基础的配置方法到各种功能的实现,探索国产操作系统的奥秘。 第一:观察结果 第二:开源语言 ArkTS是鸿蒙应用开发中使用的TypeScript超集,提供了一套丰富的API来构建应用界面和逻辑。 第三:环境搭建 步骤 1 通过如…...

MDK的编译过程及文件类型全解

本章参考资料&#xff1a;MDK的帮助手册《ARM Development Tools》&#xff0c;点击MDK界面的“help->uVision Help”菜单可打开该文件。 关于ELF文件格式&#xff0c;参考配套资料里的《ELF文件格式》文件。 在本章中讲解了非常多的文件类型&#xff0c;学习时请跟着教程的…...