Java集合(八股)
这里写目录标题
- Collection 接口
- List 接口
- ArrayList 简述
- 1. ArrayList 和 LinkedList 区别?⭐️⭐️⭐️⭐️
- 2. ArrayList 和 Array 的区别?⭐️⭐️⭐️
- ArrayList 和 Vector 区别?⭐️⭐️
- ArrayList 的扩容机制?⭐️⭐️⭐️
- Queue 接口
- 1. Queue和Deque的区别?⭐️⭐️⭐️
- 2. ArrayDeque与LinkedList区别?⭐️⭐️⭐️
- 3. PriorityQueue有什么特点?⭐️⭐️⭐️
- Set 接口
- Map 接口
- 简述HashMap
- (1)HashMap查询、删除的时间复杂度⭐️⭐️⭐️⭐️
- (2)HashMap的底层实现⭐️⭐️⭐️⭐️⭐️
- 1. HashMap和HashTable的区别
- 2. HashMap和HashSet区别⭐️⭐️⭐️⭐️
- 3. HashMap和TreeMap的区别?⭐️⭐️⭐️⭐️
- 4. CocurrentHashMap线程安全的具体实现方式/底层具体实现⭐️⭐️⭐️⭐️
!!!本文是基于javaGuide的学习和自我总结!!!
集合有两大接口
Collection和Map,Collection中存单一元素,Map中存放kv对
(图片 from javaGuide)
Collection 接口
List 接口

ArrayList 简述
public class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable{...}
ArrayList
继承了AbstractList类;
实现了List,RandomAccess,Cloneable,Serializable接口
List:表明他是一个列表,支持增删查等操作、RandomAccess:表明List集合是支持快速随机访问。注: 这只是一个标志接口,不是实现了它就能快速随机访问, 还要看类的底层逻辑 (如LinkedList就算继承了RandomAccess,也无法实现随机访问,因为它底层是链表,内存地址是不连续的 , 所以注定不可能)
Cloneable:表明它具有拷贝能力,可以进行深拷贝和浅拷贝Serializable:表明它可以进行序列化操作,也就是可以将对象转换为字节流进行持久化存储或网络传输
1. ArrayList 和 LinkedList 区别?⭐️⭐️⭐️⭐️
首先说明 :
貌似绝大多数情况都是使用ArrayList , 就算是需要用到LinkedList的情况 ,也是可以用ArrayList替代掉的 , 且性能会更好
- 是否线程安全
都不是线程安全的,因为他俩都是不同步的(源码中没有任何“同步”的想法)
- 底层数据结构
- ArrayList 底层使用的是Object数组
- ListedList 底层使用的是双向链表
- 插入和删除是否受元素位置的影响
- ArrayList 采用数组存储,所以插入和删除的时间复杂度 受元素位置的影响。
比如: 执行 `add(E e)`方法时,ArrayList会默认在末尾追加元素,时间复杂度是O(1) 执行`add(int index, E element)`,ArrayList会让第i个及以后元素 全部移动一位,时间复杂度是O(n)
- ListedList 采用链表存储,插入、删除头尾元素不受影响,指定索引的插入删除操作受影响
执行`add(E e)` `addFirst(E e)``addLast(E e)``removeFirst()``removeLast()` 时间复杂度为O(1) 执行`add(int index, E element)` `remove(Object o)` `remove(int index)`时间复杂度为O(n),因为需要先移动到指定位置再插入和删除
- 是否支持快速随机访问
ArrayList支持 --> 实现了RandomAccess的接口
ListedList不支持
- 内存空间占用
- ArrayList 的空间浪费主要体现在 : list列表结尾会预留一定容量的空间
- LinkedList 的空间花费则体现在 : 每个元素都需要消耗比ArrayList更多的空间 (因为都要存放直接后继和直接前驱以及数据)
2. ArrayList 和 Array 的区别?⭐️⭐️⭐️
- Array
Array(数组) 就是一个可以自定义固定长度的数组 , 只能按照下标访问元素 , Array里面没有定义什么便于使用的方法
最常用的可能就是Array.length() 和 Array.sort()
- ArrayList
ArrayList<Integer> list = new ArrayList();
ArrayList 内置了丰富的API操作方法 , 比如add() , remove()等
它会根据实际存储的元素动态扩容
允许使用泛型 来确保类型安全
只能存储对象
ArrayList 和 Vector 区别?⭐️⭐️
它们底层都是使用
Object()存储
- Vector比较老了 , 但它是线程安全的(很少使用了)
- ArrayList , 适用于频繁的查找工作 ; 线程不安全
ArrayList 的扩容机制?⭐️⭐️⭐️
- ArrayList的默认长度是10,当然也可以自定义
- 当数组存储的元素 数量大于10的时候,就会触发扩容机制(也就是
grow()方法)grow()方法 会创建一个新的数组,这个新数组的长度大约是原来的1.5倍(grow中的移位运算 算出来的)- 然后通过
Arrays.copyOf()方法将老数组赋值到新数组当中- 以此类推
ArrayList的扩容机制的核心其实是grow()方法
/*** 要分配的最大数组大小*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;/*** ArrayList扩容的核心方法。*/
private void grow(int minCapacity) {// oldCapacity为旧容量,newCapacity为新容量int oldCapacity = elementData.length;// 将oldCapacity 右移一位,其效果相当于oldCapacity /2,// 我们知道位运算的速度远远快于整除运算,整句运算式的结果就是将新容量更新为旧容量的1.5倍,int newCapacity = oldCapacity + (oldCapacity >> 1);// 然后检查新容量是否大于最小需要容量,若还是小于最小需要容量,那么就把最小需要容量当作数组的新容量,if (newCapacity - minCapacity < 0)newCapacity = minCapacity;// 如果新容量大于 MAX_ARRAY_SIZE,进入(执行) `hugeCapacity()` 方法来比较 minCapacity 和 MAX_ARRAY_SIZE,// 如果minCapacity大于最大容量,则新容量则为`Integer.MAX_VALUE`,否则,新容量大小则为 MAX_ARRAY_SIZE 即为 `Integer.MAX_VALUE - 8`。if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);// minCapacity is usually close to size, so this is a win:elementData = Arrays.copyOf(elementData, newCapacity);
}
Queue 接口

1. Queue和Deque的区别?⭐️⭐️⭐️
主要区别就是
Queue是单端队列
Deque是双端队列
本质上
- Queue :
public interface Queue<E> extends Collection<E> {...}- Deque :
public interface Deque<E> extends Queue<E> {...}- Deque继承了Queue接口,并且扩展了在队头和队尾增删元素的方法
- 事实上,Deque还提供有push()和pop()等其他方法,可用于模拟栈
2. ArrayDeque与LinkedList区别?⭐️⭐️⭐️
ArrayDeque和LinkedList都继承了Deque,两者有什么不同吗?
- ArrayDeque
- ArrayDeque是基于可变数组和双指针实现的;LinkedList是基于链表实现
//ArrayDeque transient Object[] elements; //数组 transient int head; //头指针 transient int tail; //尾指针
- ArrayDeque 不能添加null值,原因如下(源码);LinkedList可以
public void addFirst(E e) {if (e == null)throw new NullPointerException();elements[head = (head - 1) & (elements.length - 1)] >= e;if (head == tail)doubleCapacity(); }
- ArrayDeque是在jdk1.6才被引入的;LinkedList早就存在
- ArrayDeque 插入时存在扩容过程
- ArrayDeque性能更好
图片 from javaGuide

3. PriorityQueue有什么特点?⭐️⭐️⭐️
特点:元素出队顺序是与优先级相关的,即总是优先级最高的元素先出队
PriorityQueue会出现在手撕算法应用当中 --》堆排序、第K大的数、带权图的遍历等
Set 接口
Map 接口

简述HashMap
- Map里面存放的是KV对,且Key值不可重复(这一点很重要,事关HashSet为啥不可重复,因为HashSet直接把值存到Key上了,Value则赋值为一个虚拟的Object对象)
- 这篇文章很详细,不过比较老了:深入Java集合学习系列:HashMap的实现原理
(1)HashMap查询、删除的时间复杂度⭐️⭐️⭐️⭐️
- 如果没有元素
处理:直接插入元素或者直接返回未找到
时间复杂度:O(1)
- 如果有元素(链表)
处理:沿着链表遍历
时间复杂度:O(n)
- 红黑树
时间复杂度O(longn)
(2)HashMap的底层实现⭐️⭐️⭐️⭐️⭐️
- 基于Map接口实现
public class HashMap<K,V> extends AbstractMap<K,V>implements Map<K,V>, Cloneable, Serializable {...}
- 非线程安全
- HashMap的存储方法;解决哈希冲突
- JDK1.8之前,HashMap由 数组+链表 组成的,数组是HashMap的主题,链表则主要是为了解决哈希冲突而存在的(“拉链法”); - JDK1.8以后得HashMap在解决哈希冲突时有了较大的变化, -- 当链表的长度大于等于阈值(默认为8)时, -- 会判断当前数组的长度是否小于64, -- 如果小于64,则先进行数组扩容, -- 如果大于64,则将链表转化为红黑树,以减少搜索时间
- HashMap默认初始化大小为16,之后每次扩充,容量变为原来的2倍。并且,HashMap总是使用2的幂作为哈希表的大小
1. HashMap和HashTable的区别
注 : HashTable基本被淘汰了
- 线程安全
HashMap 线程不安全
HashTable 线程安全(HashTable内的方法基本都被synchronized修饰)
- 效率
因为线程安全问题,所以HashTable的效率会低一些
- 对Null key和Null value的支持
HashMap可以存储null的key和value,但null作为键只能有一个,null作为值可以有多个
HashTable不允许有null键和null值
- 其他区别可以从上面写的HashMap来说(HashTable几乎不用了)
2. HashMap和HashSet区别⭐️⭐️⭐️⭐️
HashSet<Object> objects = new HashSet();
HashMap<Object, Object> objectObjectHashMap = new HashMap();
- 区别:
HashMap里面存的是KV对 ;HashSet里存的是对象
HashMap的Key不可重复,Value可重复;HashSet不可重复
HashSet的add方法调用了HashMap中的put方法
// HashSet部分源码
public class HashSet<E>extends AbstractSet<E>implements Set<E>, Cloneable, java.io.Serializable
{static final long serialVersionUID = -5024744406713321676L;private transient HashMap<E,Object> map;// Dummy value to associate with an Object in the backing Mapprivate static final Object PRESENT = new Object();/*** Constructs a new, empty set; the backing <tt>HashMap</tt> instance has* default initial capacity (16) and load factor (0.75).*/public HashSet() {map = new HashMap<>();}...// 这里,调用了map的put方法,把e存到key上---》不能重复public boolean add(E e) {return map.put(e, PRESENT)==null;}
}
可以看出,HashSet底层就是基于HashMap实现的(HashSet的源码非常少,因为除了clone() , writeObject() , readObject() 是HashSet自己不得不实现之外,其他方法都是直接调用HashMap中的方法)
3. HashMap和TreeMap的区别?⭐️⭐️⭐️⭐️
相比于HashMap来说,TreeMap主要多了对集合中元素根据键排序以及对于集合内元素的搜索的能力
//HashMap
public class HashMap<K,V> extends AbstractMap<K,V>implements Map<K,V>, Cloneable, Serializable {
//TreeMap
public class TreeMap<K,V>extends AbstractMap<K,V>implements NavigableMap<K,V>, Cloneable, java.io.Serializable
- TreeMap实现了NavigableMap接口
实现NavigableMap接口让TreeMap有了对集合内元素的搜索能力
- NavigableMap接口提供了丰富的方法来探索和操作键值对
- TreeMap实现了SortedMap接口
实现SortedMap接口让TreeMap有了对集合中的元素根据键排序的能力。
- 默认是按照key的升序排序,不过我们也可以指定排序的比较器
4. CocurrentHashMap线程安全的具体实现方式/底层具体实现⭐️⭐️⭐️⭐️
分两个阶段——jdk1.8之前;1.8及以后
- jdk1.8以前

首先将数据分成一段一段(这个“端”就是Segment)的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据时,其他段的数据也能被其他线程访问
ConcurrentHashMap是由Segment数据结构和HashEntry数据结构组成
Segment的结构和1.8以前的HashMap类似
- jdk1.8及以后


相关文章:
Java集合(八股)
这里写目录标题 Collection 接口List 接口ArrayList 简述 1. ArrayList 和 LinkedList 区别?⭐️⭐️⭐️⭐️2. ArrayList 和 Array 的区别?⭐️⭐️⭐️ArrayList 和 Vector 区别?⭐️⭐️ArrayList 的扩容机制?⭐️⭐️⭐️ Qu…...
python+adb
#!/usr/bin/python env # -*- coding: utf-8 -*- import os import sys import subprocess from time import sleepimport logging logging.basicConfig(levellogging.DEBUG) class ScreenCapture():def get_screen_size(self):"""获取手机分辨率""&q…...
AIGC文本生成
文本生成是一种人工智能技术,它基于深度学习算法,根据给定的提示信息创作出有逻辑、连贯的文本内容。 文本生成所需的输入(提示或Prompt)可以是简单的关键词、一句话概述或是更复杂的指令和上下文信息。文本生成模型通过分析大量…...
系统架构设计师教程 第5章 5.4 软件测试 笔记
5.4 软件测试 5.4.1 测试方法 ★★★★★ 软件测试方法的分类有很多种, 以测试过程中程序执行状态为依据可分为静态测试 (Static Testing,ST) 和动态测试 (Dynamic Testing,DT); 以具体实现算法细节和系统内部结构的相关情况为根据可分黑盒测试、白盒测试和灰盒测…...
ASPICE评估全流程解析:汽车软件开发组织能力的系统化评估
ASPICE(Automotive SPICE)评估的过程是一个系统化和详尽的流程,旨在评估汽车软件开发组织在软件开发过程方面的能力。 以下是ASPICE评估过程的详细描述: 1. 评估准备阶段 a. 确定评估目标和范围 明确评估的目标,如评…...
合并RAR分卷压缩包
因为文件压缩之后体积仍然过大,大家可能会选择进行分卷压缩,那么rar分卷压缩包之后如何合并成一个压缩包文件呢?今天我们来学习rar分卷压缩包,合并成一个的方法。 最基础的方法就是将分卷压缩包解压出来之后,再将文件…...
重生奇迹MU 想去哪就去哪玩 轻松玩转翅膀属性
在重生奇迹MU这个游戏中,玩家需要扫荡各种怪物,勇斗BOSS,与其他玩家激战。在这个充满冒险的旅程中,翅膀是最重要的装备之一。拥有一个属性强大的翅膀,代表着玩家的成长与强大。穿上它,加速你的冒险之旅吧&a…...
Lnux-gcc/g++使用
目录 1.gcc/g介绍 1.什么是 gcc / g 2.gcc/g指令格式 2. gcc / g 实现程序翻译的过程 1.预处理(进行宏替换) 2.编译(生成汇编) 3.汇编(生成机器可识别代码) 4.连接(生成可执行文件或库文件) 1.gcc/g介绍 1.什么…...
用Python创建一个键盘输入捕获程序
目录 简介 环境准备 安装依赖 项目结构 编写代码 1. 导入库 2. 定义回调函数 3. 启动键盘监听器 4. 整合代码 运行程序 结论 简介 在这篇博文中,我们将探索如何使用Python编写一个简单的键盘输入捕获程序。这个程序将实时捕获用户的键盘输入并在控制台中显示出来。…...
Mybatis中Like模糊查询三种处理方式
目录 Mybatis中Like模糊查询三种处理方式 1.通过单引号拼接${} 1)mapper接口 2)Mapper.xml 3)测试代码 4) 测试结果 2.通过concat()函数拼接(个人推荐使用这种) 1)mapper接口 2)Mapper.xml 3)测试代码 4) 测…...
STL值list
list容器 头文件:#include<list> - list是一个双向链表容器,可高效地进行插入删除元素 - list不可以随机存取元素,所以不支持at.(pos)函数与[]操作符 注:list使用迭代器访问数据时可以一步一步走自增自减(即…...
结构体的内存对齐
对⻬规则: 1.结构体的第⼀个成员对⻬到和结构体变量起始位置偏移量为0的地址处 2.其他成员变量要对⻬到某个数字(对⻬数)的整数倍的地址处。 对⻬数编译器默认的⼀个对⻬数与该成员变量⼤⼩的较⼩值。 但一些编译器下并没有默认对其数 3.结…...
Web 创建设计
Web 创建设计 Web 创建设计是一个涉及多个方面的过程,它包括网站的视觉设计、用户界面设计、用户体验设计、前端开发以及后端开发等。本文将详细介绍这些方面,并探讨如何创建一个既美观又实用的网站。 1. 视觉设计 视觉设计是网站创建设计的第一步,它决定了网站的外观和感…...
2024年9月16日历史上的今天大事件早读
1151年9月16日 南宋名将韩世忠逝世 1782年9月16日 清朝道光帝旻宁出生 1810年9月16日 墨西哥独立日 1856年9月16日 云南杜文秀领导回民起义 1880年9月16日 左宗棠创办的兰州机器织呢局开工 1908年9月16日 美国通用汽车公司成立 1919年9月16日 周恩来组织参加的觉悟社成立…...
记录工作中遇到的问题(持续更新~)
跨域问题(待排查) 2024-09-15 【前提】:前端配置了nignx转发,后端设置了跨域拦截,对http://xxxx做了允许跨域。但是访问http://xxx被拦截了,返回403 Forbidden。同样的配置放在另外一套部署的环境上就完全…...
六西格玛咨询:石油机械制造企业的成本控制与优化专家
一、石油机械制造行业现状及主要困扰 随着全球能源需求的日益增长,石油开采和生产设备需求不断增加,石油机械制造行业在过去数十年里得到了迅猛发展。然而,石油机械制造作为一个高度复杂且技术密集的行业,也面临着多重挑战。首先…...
Redis基础数据结构之 quicklist 和 listpack 源码解读
目录标题 quicklist为什么要设计 quicklist?quicklist特点ziplist quicklist数据结构 listpacklistpack是什么?listpack数据结构ziplist干啥去了?为什么有listpack?什么是ziplist的连锁更新?listpack 如何避免连锁更新࿱…...
深入理解Go语言的方法定义与使用
在Go语言编程中,方法(Method) 是附属于特定类型的函数,使我们能够以面向对象的方式编写代码。通过方法,我们可以更自然地对类型进行操作。本文将通过实际的代码示例,深入探讨Go语言中方法的定义与使用。 一…...
堆排序,快速排序
目录 1.堆排序 2.快速排序 1.hoare版本 2.挖坑法 3.前后指针法 注意点 1.堆排序 void Swap(int* a, int* b) {int tmp *a;*a *b;*b tmp; } void adjustdown(int* a, int n, int parent) {int child parent * 2 1;while (child < n){if (child 1 < n &&am…...
系统架构师---数据库设计的四个阶段
需求分析、概念设计、逻辑设计和物理设计是数据库设计中的四个关键阶段,每个阶段都有其独特的任务和目标,以下是对这四个阶段的区别的详细阐述: 需求分析阶段 目标:全面理解用户对数据库系统的需求,包括业务需求、信…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...
uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...
libfmt: 现代C++的格式化工具库介绍与酷炫功能
libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库,提供了高效、安全的文本格式化功能,是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全:…...
Xela矩阵三轴触觉传感器的工作原理解析与应用场景
Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知,帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量,能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度,还为机器人、医疗设备和制造业的智…...
Axure 下拉框联动
实现选省、选完省之后选对应省份下的市区...



