面试必问的Java集合:从源码到实践,那些你未必说清的底层逻辑

Java集合常见面试题总结 但是,使用数组存储对象存在一些不足之处,因为在实际开发中,存储的数据类型多种多样且数量不确定。与数组相比,Java 集合提供了更灵活、更有效的方法来存储多个数据对象。Java 集合框架中的各种集合类和接口可以存储不同类型和数量的对象,同时还具有多样化的操作方式。相较于数组,Java 集合的优势在于它们的大小可变、支持泛型、具有内建算法等。总的来说,Java 集合提高了数据的存储和处理灵活性,可以更好地适应现代软件开发中多样化的数据需求,并支持高质量的代码编写。我们主要根据集合的特点来选择合适的集合。 阅读详情

在Java面试中,集合框架永远是最核心的考察点之一。无论是刚入门的应届生,还是有一定经验的开发者,"说说ArrayList和LinkedList的区别""HashMap的扩容机制"这类问题总能精准戳中知识盲区。今天这篇文章,我不会照本宣科地罗列集合类的特性,而是结合​​源码细节、生产踩坑案例、面试高频问题​​,带你从"会用"升级到"精通"。


一、为什么说集合是Java的"地基"?

Java集合框架(Java Collections Framework)提供了高效的数据结构和算法,覆盖了90%以上的业务场景需求。它的设计遵循​​接口-实现分离​​原则:

  • ​​接口层​​(如List/Set/Queue/Map)定义行为规范;
  • ​​实现层​​(如ArrayList/HashSet/HashMap)提供具体功能;
  • ​​工具类​​(如Collections/Arrays)封装通用操作。

这种设计让开发者能根据场景灵活选择:需要快速随机访问选ArrayList,需要去重选HashSet,需要键值对存储选HashMap。但看似简单的选择背后,藏着无数细节——比如ArrayList扩容时的性能损耗,HashMap哈希冲突的解决策略,这些都会直接影响系统的稳定性和性能。


二、List家族:顺序与随机的博弈

1. ArrayList:动态数组的"成长烦恼"

ArrayList是最常用的列表实现,基于​​动态数组​​实现。它的核心特点是:

  • ​​随机访问快​​:通过索引直接计算内存地址(O(1)时间复杂度);
  • ​​增删慢​​:插入/删除元素需要移动后续元素(最坏O(n)时间复杂度);
  • ​​自动扩容​​:初始容量默认10,扩容时按​​1.5倍​​增长((oldCapacity >> 1) + oldCapacity)。
面试高频问题:ArrayList的扩容机制到底有多耗时?

很多人知道ArrayList扩容会复制数组,但很少有人能说清具体过程。我们看源码(JDK1.8):

private void grow(int minCapacity) {
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1); // 1.5倍扩容
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity > MAX_ARRAY_SIZE)
        newCapacity = hugeCapacity(minCapacity);
    elementData = Arrays.copyOf(elementData, newCapacity); // 关键复制操作
}

这里的Arrays.copyOf会创建一个新数组,并将旧数组元素逐个复制过去。假设初始容量是10,插入第11个元素时,会扩容到15;插入第16个元素时,扩容到22(15 * 1.5=22.5,取整为22)。如果一次性插入大量元素(比如批量导入数据),频繁扩容会导致多次数组复制,严重影响性能。

​​生产踩坑案例​​:某电商系统在初始化商品列表时,一次性插入10万条数据。由于未指定初始容量,ArrayList默认从10开始扩容,总共触发了7次扩容(10→15→22→33→49→73→109→163),每次扩容都要复制之前所有元素。最终耗时比预期的3秒多了2秒——这就是典型的"数组复制陷阱"。

解决方案:初始化时指定合理容量

如果已知数据量,建议提前设置initialCapacity:

List<Product> productList = new ArrayList<>(100000); // 初始容量10万
// 后续插入无需扩容,性能提升显著

2. LinkedList:链表的"空间换时间"

LinkedList基于​​双向链表​​实现,每个节点包含prev和next指针。它的特点是:

  • ​​随机访问慢​​:需要从头节点开始遍历(O(n)时间复杂度);
  • ​​增删快​​:只需修改相邻节点的指针(O(1)时间复杂度,前提是已知节点位置);
  • ​​额外空间开销大​​:每个节点需要存储前后指针(占24字节,而ArrayList的数组元素仅存数据)。
面试高频问题:LinkedList的addFirst()为什么比ArrayList的add(0, element)快?

ArrayList的add(0, element)需要将后续所有元素后移(System.arraycopy),时间复杂度O(n);而LinkedList的addFirst()只需修改头节点的prev指针,时间复杂度O(1)。但如果是LinkedList.get(10000),则需要遍历10000次指针——这时候ArrayList的优势就体现出来了。


三、Set家族:去重的"艺术"

1. HashSet:基于HashMap的去重

HashSet的底层是HashMap,通过key存储元素,value统一为PRESENT(一个静态的Object对象)。它的核心逻辑是:

  • 元素唯一性由HashMap的key唯一性保证;
  • 无序性(不保证插入顺序,也不保证迭代顺序)。
面试高频问题:HashSet如何判断元素重复?

调用add(E e)时,本质是调用map.put(e, PRESENT)。如果返回null,说明e是新的(map中不存在该key);如果返回非null,说明e已存在(因为HashMap的key不允许重复)。

​​注意​​:如果元素的hashCode()和equals()方法被重写,必须保证两者的逻辑一致——否则可能出现"元素重复但HashSet认为不重复"的bug。例如:

class User {
    private int id;
    public User(int id) { this.id = id; }
    @Override
    public int hashCode() { return id % 10; } // 哈希值只取个位
    @Override
    public boolean equals(Object o) { 
        return o instanceof User && ((User) o).id == this.id; // 实际比较id
    }
}

// 测试:两个不同id但哈希值相同的User会被HashSet视为不同元素吗?
Set<User> set = new HashSet<>();
set.add(new User(11)); // 哈希值1
set.add(new User(21)); // 哈希值1
System.out.println(set.size()); // 输出2(因为equals比较id不同)

2. TreeSet:有序的"红黑树"

TreeSet基于​​红黑树​​(一种自平衡二叉搜索树)实现,元素默认按自然顺序排序(或通过Comparator自定义)。它的特点是:

  • ​​有序性​​:插入、删除、查询的时间复杂度都是O(logn);
  • ​​不允许重复​​:通过compareTo或Comparator判断元素是否相等(若compareTo返回0,则视为相等)。
面试高频问题:TreeSet的排序规则是怎么确定的?

如果元素实现了Comparable接口(如Integer/String),则使用compareTo方法;否则需要在创建TreeSet时传入Comparator。例如:

// 按字符串长度排序
Set<String> set = new TreeSet<>((s1, s2) -> s1.length() - s2.length());
set.add("apple"); // 长度5
set.add("banana"); // 长度6
set.add("pear"); // 长度4
System.out.println(set); // 输出[pear, apple, banana]

四、Map家族:键值对的"江湖"

1. HashMap:最常用的键值存储

HashMap的底层是​​数组+链表+红黑树​​的组合结构(JDK1.8引入红黑树优化哈希冲突)。核心逻辑如下:

  • ​​初始化​​:默认容量16,负载因子0.75(空间与时间的权衡);
  • ​​哈希计算​​:key.hashCode()的高16位与低16位异或(减少哈希冲突);
  • ​​扩容机制​​:当元素数量超过容量*负载因子时,触发扩容(新容量=旧容量*2);
  • ​​冲突解决​​:
    • 哈希值相同(链地址法):先尝试插入链表,若链表长度≥8且容量≥64,转为红黑树;
    • 红黑树节点过多:当节点数<6时,退化为链表。
面试高频问题:HashMap的扩容为什么是2的幂次?

答案藏在indexFor方法中:

static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

// 计算桶的索引
int i = (n - 1) & hash; // n是容量(2的幂次)

如果容量是2的幂次(如16→32→64),(n-1)的二进制是全1(如15→1111,31→11111),与hash按位与运算相当于取hash的低log2(n)位。这样扩容时,只需要判断hash的第log2(旧容量)位是否为0,就能决定元素留在原桶还是迁移到新桶(即所谓的"平滑扩容")。如果容量不是2的幂次,这种位运算的优化就无法实现,扩容时的重新哈希会更复杂。


2. ConcurrentHashMap:线程安全的"进化史"

ConcurrentHashMap是线程安全的哈希表,其实现随着JDK版本不断优化:

  • ​​JDK1.7​​:分段锁(Segment数组+HashEntry数组),每个Segment独立加锁,并发度为Segment数量(默认16);
  • ​​JDK1.8​​:放弃分段锁,改用CAS+synchronized,锁粒度缩小到桶的头节点,并发度更高。
面试高频问题:ConcurrentHashMap如何保证线程安全?

JDK1.8的核心逻辑:

  1. ​​CAS插入​​:当桶为空时,通过CAS尝试插入新节点(tabAt和casTabAt方法);
  2. ​​synchronized加锁​​:当桶已有节点(可能是链表或红黑树),则对头节点加synchronized锁,保证同一时刻只有一个线程修改该桶;
  3. ​​树化与反树化​​:链表长度≥8且容量≥64时转为红黑树,提升查询效率;红黑树节点数<6时退化为链表,减少内存占用。

​​生产踩坑案例​​:某高并发系统中,使用ConcurrentHashMap存储用户会话信息,发现QPS上不去。通过jstack排查发现,大量线程卡在put操作的锁竞争上——原因是业务代码中频繁操作同一个桶(比如所有用户的userId哈希值都落在同一个桶)。后来通过自定义HashFunction分散哈希值,QPS提升了3倍。


五、面试避坑指南:这些"坑"你踩过吗?

1. 误区:"Vector比ArrayList线程安全,所以更推荐"

Vector的方法(如add/get)都用synchronized修饰,确实是线程安全的。但它的锁粒度太大(整个数组),并发效率远低于CopyOnWriteArrayList或Collections.synchronizedList。​​除非明确需要兼容旧代码,否则不建议使用Vector​​。

2. 误区:"HashMap的key可以是null,但value不能是null"

实际上,HashMap允许key和value都为null(key为null时存储在索引0的位置)。而Hashtable的key和value都不允许为null(会抛出NullPointerException)。

3. 误区:"LinkedHashMap是有序的,所以适合做缓存"

LinkedHashMap默认按插入顺序排序,可通过构造函数new LinkedHashMap<>(16, 0.75f, true)改为按访问顺序排序(最近访问的元素放在最后)。这确实适合实现LRU缓存(最近最少使用),但需要注意:如果并发修改,需要额外加锁。


六、总结:集合框架的底层逻辑链

Java集合的设计哲学是​​用最小的复杂度解决大部分问题​​:

  • ​​List​​:用数组(ArrayList)或链表(LinkedList)实现顺序存储;
  • ​​Set​​:用哈希表(HashSet)或红黑树(TreeSet)实现去重和排序;
  • ​​Map​​:用数组+链表+红黑树(HashMap)或CAS+synchronized(ConcurrentHashMap)实现高效键值对存储。

理解这些底层逻辑后,你不仅能轻松应对面试,还能在实际开发中:

  • 根据场景选择合适的集合类(如需要快速随机访问选ArrayList,需要线程安全选ConcurrentHashMap);
  • 预判性能瓶颈(如批量插入时初始化ArrayList容量,避免频繁扩容);
  • 解决常见问题(如HashMap的哈希冲突、ConcurrentHashMap的锁竞争)。

最后送大家一句话:​​集合框架的每个设计细节,都是前人用性能和bug换来的经验​​。

面试必备:Java集合源码浅析 说明:以下内容的分析源码,如没有特别说明,均来自JDK8.集合主要分为两组:单列集合和双列集合 单列集合一般是指存放单个对象的集合,而双列集合一般是以键值对形式存放的数据的集合。接口下有两个重要的子接口 ,,他们的实现子类都是单列集合。接口的实现子类有 、、,也都是双列集合。以下是集合类下两大主接口的类图关系。由于 接口直接继承了 ,它是没有实现的,它的所有方法都是由它的子接口的实现类进行实现,所以这里就以 下子接口 的实现类 来讲解。注意 是有序集合且元素可以重复,而 则是无序集合,元素不可重复 阅读详情

相关推荐

告别数据丢失焦虑:用Python手把手实现Reed-Solomon码(附完整代码)

本文详细介绍了如何使用Python实现Reed-Solomon纠错码(RS码),帮助开发者有效防止数据丢失。通过基础编解码实战、文件保护方案和高级性能优化技巧,读者可以轻松掌握这一前向纠错技术,应用于物联网、文件存储和网络传输等场景,提升数据可靠性。

weixin_42527160的博客 224

Java集合面试题

Java集合面试题 Java 集合框架的基础接口有哪些? Collection ,为集合层级的根接口。一个集合代表一组对象,这些对象即为它的元素。Java 平台不提供这个接口任何直接的实现。 Set ,是一个不能包含重复元素的集合。这个接口对数学集合抽象进行建模,被用来代表集合,就如一副牌。 List ,是一个有序集合,可以包含重复元素。你可以通过它的索引来访问任何元素。List 更像长度动态...

木村的博客 2万+

致远OA公文管理模块相关操作

致远oa协同办公系统 公文管理模板 相关操作

weixin_59666050的博客 4279

从源码到实践:Java集合框架面试核心知识点全解析

在Java开发中,集合框架(Java Collections Framework)是最基础也最常用的工具集。无论是处理业务逻辑时的数据暂存,还是高性能场景下的算法优化,集合的使用都贯穿始终。因此,Java集合相关的面试题几乎是所有技术面试的“必考项”。本文将从​​底层原理、高频问题、常见误区​​三个维度,结合源码和实践场景,帮你彻底掌握集合框架的核心知识点。

🚩 Flag:今年绝不写屎山代码(去年也是这么说的) 1173

20240128 C#与SCPI协议实战:轻量级仪器控制库ScpiNet应用指南

本文详细介绍了轻量级C#库ScpiNet在仪器控制中的应用。相较于传统的NI-VISA,ScpiNet无需安装庞大运行时,通过纯C#实现直接与USB或以太网设备通信,支持跨厂商SCPI仪器。文章提供了从快速连接到实战封装、错误处理的完整指南,帮助开发者构建简洁高效的自动化测试系统。

h9j8k7l6m5n的博客 549

特斯拉 Model 3解析(九)特斯拉 Model 3 自动驾驶域控制器硬件架构

硬件层:车规级高密度主板 → PI/SI优化到极致传感器层:三目摄像头主导视觉,雷达补充冗余,超声波保证近距设计理念:依靠芯片算力最大化视觉潜力,而不是堆传感器这套思路的优点是:成本可控、量产快、迭代快。缺点是:极端场景下感知鲁棒性不足。纯视觉方案短期可行,但中长期必然要重新引入高分辨率雷达甚至固态LiDAR作为冗余。电源/信号完整性会越来越关键,未来域控板设计会越来越像数据中心服务器。

weixin_43199439的博客 1789

【面试突击】Java面试底层逻辑(HashMap、ConcurrentHashMap面试实战)

欢迎关注公众号(通过文章导读关注:【11来了】),及时收到 AI 前沿项目工具及新技术 的推送 发送 资料 可领取 深入理解 Redis 系列文章结合电商场景讲解 Redis 使用场景、中间件系列笔记和编程高频电子书! 文章导读地址:点击查看文章导读! 感谢你的关注!

qq_45260619的博客 1392

Windsurf 入门指南:从安装到实战(免费AI IDE新选择)

本文是Windsurf AI IDE的详细入门指南,涵盖从下载安装到核心功能实战的全过程。通过对比分析,文章指出Windsurf凭借其免费、小白友好的特性及强大的上下文感知能力,成为学习编程和提升开发效率的新选择,特别适合零基础开发者和寻求高效AI编程工具的开发者。

weixin_29237635的博客 857

【2025最新】Java面试必问:HashMap夺命连环10问!(附红黑树图解+源码剖析)

数据结构演进:数组+链表→数组+链表/红黑树的优化逻辑;红黑树转换:阈值8和6的原理,树化与退化条件;扩容机制:2的幂次方容量、高位分拆迁移、负载因子作用;线程安全:问题及解决方案(ConcurrentHashMap)。面试加分项能手写方法或解释哈希扰动函数;结合泊松分布解释红黑树阈值选择;对比JDK 1.7和1.8的实现差异及性能优化点。

架构师之路 1296

【Bluetooth蓝牙开发】一、开篇词 | 打造全网最详细的Bluetooth开发教程

1、开篇词 2、蓝牙开发入门 3、蓝牙协议栈总览 4、蓝牙协议栈——物理层 5、蓝牙协议栈——链路层 6、蓝牙协议栈——传输层 7、蓝牙协议栈——L2CAP协议 8、蓝牙协议栈——ATT协议 9、蓝牙协议栈——GATT协议 10、蓝牙通信流程分析 11、蓝牙协议栈——Bluez交叉编译 12、蓝牙调试工具汇总

Donge's Blog 1万+

Bean named‘ddlApplicationRunner‘is expected to be of type ‘org.springframework.boot.Runner‘

springboot3.1.7整合mybatisplus3.5.3.2版本报错,sringboot3.x整合myabtis报错

雾林小妖的博客 1万+

细节决定成败,java面试必问底层

小编利用空余时间整理了一份《MySQL性能调优手册》,初衷也很简单,就是希望能够帮助到大家,减轻大家的负担和节省时间。关于这个,给大家看一份学习大纲(PDF)文件,每一个分支里面会有详细的介绍。这里都是以图片形式展示介绍,如要下载原文件以及更多的性能调优笔记(MySQL+Tomcat+JVM)!一份学习大纲(PDF)文件,每一个分支里面会有详细的介绍。[外链图片转存中…(img-EqXgV7Wa-1711094237559)]

weixin_42179304的博客 824

【异常】API 速率限制报错问题全流程排查与解决指南 API rate limit reached. Please try again later.

摘要: 本文针对大模型API开发中常见的速率限制报错("API rate limit reached")提供全流程解决方案。首先解析该报错的本质是服务端对高频调用的保护机制,通过三步排查法确认根因:客户端请求频率超出账户阈值。提出三级解决方案:1)临时等待限流周期重置;2)升级付费账户提高调用配额;3)构建多模型容灾架构实现自动切换。建议生产环境优先采用容灾方案,通过备用API节点保障业务连续性,同时平衡不同模型服务的成本与性能。

奶爸的编程之路,也就一周冷个三天 1440

【Java基础】面试必问:HashMap、HashTable与HashSet的区别、联系与实践指南

本文深入解析Java中HashMap、HashTable和HashSet的核心特性与区别。HashMap采用哈希表实现,非线程安全但性能高效,支持null键值;HashTable虽线程安全但因全局锁性能低下,已被ConcurrentHashMap取代;HashSet本质是基于HashMap实现的唯一元素集合。三者底层均依赖哈希计算与冲突处理机制,但JDK1.8对HashMap引入红黑树优化查询效率。开发者应根据线程安全、null支持和性能需求选择合适实现,避免误用导致性能问题或逻辑错误。

1157

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

【面试必刷】Java集合框架源码剖析:HashMap、ConcurrentHashMap、ArrayList等线程安全之道

Java集合框架是面试中的高频考点,也是日常开发的基础。本文将带你深入HashMap、ConcurrentHashMap的源码,探究其扩容机制、哈希冲突解决、红黑树转换以及线程安全原理。同时,我们也会对比ArrayList与LinkedList的特性与源码,解析HashSet、TreeSet的底层实现,并总结各种集合类的线程安全版本及其实现机制。准备好了吗?让我们一起开启这场源码之旅!

weixin_57361509的博客 900

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

一文彻底搞懂 HashMap 底层实现:高频面试必考,附源码解析!

在 Java 开发中,HashMap是最常用的集合之一,用于存储键值对数据。由于它广泛应用于缓存、内存存储、中间结果等场景,因此面试官极为关注候选人是否真正理解其底层数据结构哈希冲突解决机制扩容机制等核心原理。HashMap 常作为中高级 Java 后端面试中对“基础功底”和“源码理解能力”的重要考察点。掌握 HashMap 的底层原理,不仅能帮助你应对高频面试题,更能在项目开发中写出更高性能的代码。多看源码:如putVal()resize()方法的实现。自己实现一个简易版 HashMap,加深理解。

残影的博客 838

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

面试高频知识点整理——集合篇(包含底层源码)

集合知识点整理集合的概念集合的简要结构图集合的应用场景Collection接口collection常用方法collection集合的遍历方式List接口List接口常用的方法ArrayList实现类JDK1.7时的源码 集合的概念         关于集合,首先我们得知道什么是集合,集合的概念是什么,这是最基础的,也是最基本的,那后面面试官问什么,才有可能一一答来。那什么是集合呢? 集合类存放在java.util包中 集合类主

qq_46540738的博客 617

面试必看:Java 集合面试高频题总结:从原理到实战的回答技巧

本文总结了Java集合框架的12道高频面试题,重点解析了ArrayList和LinkedList的核心原理与使用场景。ArrayList基于动态数组实现,适合高频查询;LinkedList采用双向链表结构,适合频繁插入删除。文章提供了结构化回答模板和实战技巧,如性能优化建议和常见陷阱(如Arrays.asList返回不可变列表)。同时强调算法复杂度分析的重要性,指导开发者根据实际场景选择合适集合类,并通过具体案例说明错误使用带来的性能问题及解决方案。

xxxxxxllllllshi的博客 728

java集合深入理解(一):java集合掌握多少才算合格

(一)概述 java集合是写代码时经常用到,面试时经常问到的一项基础知识。因此了解深入了解集合不管对写代码,或者是面试都有很大的帮助。作为一名合格的java程序员,你需要了解以下关于集合的知识: 1.集合的框架体系 2.Collection接口的特点和使用 3.List和Set接口的特点和使用 4.List接口和Set接口的实现类学习 5.Map接口的特点和使用 6.Map接口的实现...

Java鱼仔的博客 2372

Java互联网面试连环炮--集合

Java互联网面试连环炮--集合概述Java集合连环炮 概述 大家好,从本篇博客开始,我将和大家一起分析互联网常见的一些面试题,以及面试题背后的知识体系。为什么叫做面试连环炮呢,互联网公司的面试官一般会由表及里,根据面试者的回答,一环一环的问,直到面试者回答不上来,或者面试官觉得这块知识面试者已经掌握的比较好了,这种面试的形式被网上称之为连环炮。本篇先从Java基础中的集合开始。 Java集合连环...

ReStartForTD 1161

Java集合框架面试指南:HashMap源码到实战

Java集合框架面试指南:HashMap源码到实战 本文深入解析Java集合框架的整体架构与设计思想,重点剖析HashMap的底层实现原理、扩容机制和性能优化策略。通过对ArrayList、LinkedList、Vector的性能对比分析,以及ConcurrentHashMap的线程安全实现机制,为开发者提供全面的集合框架面试指南和实战指导。 Java集合框架整体架构与设计思想 Java集合框架是...

gitblog_00390的博客 1078

2024大厂Java面试必问题目,京东java面试题技术面

在开头跟大家分享的时候我就说,面试我是没有做好准备的,全靠平时的积累,确实有点临时抱佛脚了,以至于我自己还是挺懊恼的。(准备好了或许可以拿个40k,没做准备只有30k+,你们懂那种感觉吗)如何准备面试?1、前期铺垫(技术沉积)程序员面试其实是对于技术的一次摸底考试,你的技术牛逼,那你就是大爷。大厂对于技术的要求主要体现在:基础,原理,深入研究源码,广度,实战五个方面,也只有将原理理论结合实战才能把技术点吃透。

2401_83330193的博客 955

Java常见集合一条龙讲解版(结合底层原理以及面试题)

本文由浅至深讲解了Java常见集合的原理,并结合了常见Java集合的面试题进行讲解,保证你一定会有些收获。

2302_79761426的博客 1181

2024 Java面试必问:HashMap底层原理深入解析(JDK1.8)

答太小:空间利用率低,频繁扩容-太大:空间利用率高,但hash碰撞增多,性能下降0.75是时间和空间的平衡点,扩容后节点分布更均匀HashMap是Java中最重要也最复杂的集合类之一,掌握其底层原理对于面试和实际开发都至关重要。核心知识点总结:✅数据结构:JDK1.8 = 数组 + 链表 + 红黑树✅核心机制:hash计算、put/get流程、扩容机制✅优化点:红黑树、尾插法、无需rehash✅线程安全:HashMap线程不安全,并发用ConcurrentHashMap。

2301_80211654的博客 361

Java基础--1-Java避坑|== 和 equals 别再用错了!从Object源码到HashSet,一次性讲懂底层逻辑

hashCode的作用:给对象“分组”,帮助哈希集合快速定位存储位置,提高查询和存储效率;equals的作用:在同一个哈希桶内,判断两个对象是否“真正重复”(逻辑上相等);两者的关系equals为true→hashCode必须相同;hashCode不同 →equals必须为false;hashCode相同 →equals不一定为true(可能出现哈希碰撞,但不影响正常使用)。操作比较什么是否可重写使用场景==引用地址(身份)❌ 不可判断是否同一对象equals()逻辑相等(内容)

weisian的博客 2万+

Java-常见面试题-集合-总结

为了能让 HashMap 存取高效,尽量较少碰撞,也就是要尽量把数据分配均匀。我们上面也讲到了过了,Hash 值的范围值-2147483648 到 2147483647,前后加起来大概 40 亿的映射空间,只要哈希函数映射得比较均匀松散,一般应用是很难出现碰撞的。但问题是一个 40 亿长度的数组,内存是放不下的。所以这个散列值是不能直接拿来用的。用之前还要先做对数组的长度取模运算,得到的余数才能用来要存放的位置也就是对应的数组下标。这个数组下标的计算方法是“(n 代表数组长度)。

Java程序员的知识博客 1126
上一篇: Redis KEYS * 与 SCAN:一字之差,天壤之别!生产环境避坑必看
下一篇: 面试被追着问的Java多线程生命周期:从青铜到王者,我悟了!
码里看花‌
博客等级 码龄8年 321粉丝 68原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码里看花‌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值