List和Map篇

大家好我是小明,今天消学习集合,这是我已经学习过的总结。


文章目录

  • [1. List相关面试题](#1. List相关面试题)
  • [2. HashMap面试题](#2. HashMap面试题)
    • 2.1哈希表底层原理
    • [2.2 HashMap的put方法具体流程](#2.2 HashMap的put方法具体流程)
    • [2.3 hashMap的寻址算法是什么??](#2.3 hashMap的寻址算法是什么??)

总体学习大纲

1. List相关面试题

1.1 数组

数组是用一种连续的内存空间 来存储 相同数据类型 的线性结构


为啥数据索引从0开始呢,假如从1开始不行吗?

  • 在根据数组索引获取元素的时候,会用索引和寻址公式来计算内存所对应的元素数据,寻址公式是:数组的首地址 + 索引乘以存储数据的类型大小
  • 如果数组的索引从 1 开始,寻址公式中,就需要增加一次减法操作,对于 CPU 来说就多了一次指令,性能不高。

总结:

  • 数组是用一种连续的内存空间 来存储 相同数据类型 的线性结构
  • 数组下标从0开始
  • 通过下标查询时间复杂度O(1),查找(未知元素,未知下标)时间复杂度O(n),查找(未知元素,未知下标,元素排序)时间复杂度O(logn)
  • 插入和删除数据需要数据挪动,时间复杂度O(n)

自定义排序:

实现Comparator(比较器)接口的compare方法


1.2ArrayList底层原理是什么??

下面是是基本代码

  • ArrayList 底层是用动态的数组(实现自动扩容动态的数组)实现的
  • ArrayList 初始容量为 0,当第一次添加数据的时候才会初始化容量为 10
  • ArrayList 在进行扩容的时候是原来容量的 1.5 倍(copyOf方法),每次扩容都需要拷贝数组

还有这个


1.3 LinkedList相关面试题

总体复习大纲

查询的平均复杂度O(n),删除的也是O(n)

ArrayLsit和LinkedList的区别是什么??

  1. 底层数据结构

ArrayList底层是动态数组,LinkedList底层是双向链表
2. 操作数据效率

ArrayList查找时间复杂度是O(1),删除和插入的时间复杂度O(n)
3. 占用内存空间

ArrayList底层是数组,内存连续,比较节省内存

LinkedList双向链表需要存储数据,和两个指针,占用内存更大
4. 线程安全

两个都不是线程安全的

可以使用这两个

List syncArrayList = Collections.synchronizedList(new ArrayList<>());

List syncLinkedList = Collections.synchronizedList(new LinkedList<>());


2. HashMap面试题

2.1哈希表底层原理

散列表(Hash Table),也叫哈希表,是一种通过键(Key)直接访问值(Value)的数据结构,核心是利用哈希函数(Hash Function)将键映射到数组的某个索引位置,从而实现O (1) 时间复杂度的高效增删改查。

哈希碰撞就是不同的键(Key),通过同一个哈希函数计算后,得到了相同的哈希值(数组索引)

哈希碰撞解决办法??

链表法

把哈希冲突的数据通链表的方式连接起来,但是如果同一个哈希桶的哈希冲突过多,就会出现很长的链表,链表查找的时间为O(n),所以当链表过长时,HashMap 会把链表转成红黑树,进一步优化查询效率。


2.2 HashMap的put方法具体流程

jdk1.8之后

  1. 参数校验与数组初始化: 首先检查底层数组 table 是否为空或长度为 0,如果是,先执行 resize() 方法初始化数组。
  2. 计算哈希值,定位数组索引
  3. 判断当前索引位置是否为空: 如果 table[i] == null,直接新建一个普通节点(Node)放入该位置。
  4. 处理索引位置非空的情况(哈希碰撞):新增链表节点后,判断链表长度是否 ≥ 8,且数组长度 ≥ 64:满足则将链表转为红黑树。
  5. 触发扩容: 最后判断当前元素数量 size 是否超过阈值(capacity × loadFactor,默认 16×0.75=12):超过则执行 resize() 扩容(数组长度翻倍)。

扩容时所有的元素都重新运算hash值重新放到新的hash表中。jdk1.7是判断是否要扩容在执行put操作,jdk1.8之后是put操作在判断是否要扩容。


2.3 hashMap的寻址算法是什么??


核心结论是 :HashMap 基于「哈希函数 + 位运算」实现寻址,核心公式是 索引 = (数组长度 - 1) & 哈希值,而非传统的取模运算。


好了今天就到这里

相关推荐
曹牧2 小时前
Java:包含空字符字段的对象序列化为JSON字符串
java·开发语言
黎雁·泠崖2 小时前
Java方法重写Override:规则+底层本质+与重载区别
java·开发语言
猿小羽2 小时前
Spring AI + MCP 实战:构建标准化 AI 智能代理与上下文集成
java·spring boot·llm·ai agent·spring ai·anthropic·mcp
高山上有一只小老虎2 小时前
mybatisplus分页查询版本 3.5.8 以下和版本 3.5.9及以上的区别
java·spring boot·mybatis
王同学 学出来2 小时前
React实操案例(四)
开发语言·react.js·前端框架
哪里不会点哪里.2 小时前
Spring Boot 项目搭建过程
java·spring boot·后端
李少兄2 小时前
FHIR 资源查询实战指南:从 HTTP 接口到 Java 客户端的完整实现
java·网络协议·http
zhengfei6112 小时前
一种综合性的现代架构模型,用于集成平台解决方案和工具,以支持专业的红队。
开发语言·人工智能·网络安全·架构·信息与通信
Stecurry_302 小时前
Spring Boot 深度进阶:从配置管理到生产级实践
java·spring boot·后端