Java常用集合(List、Map)类型相关问题整理

news2024/9/21 17:38:31

一、背景

针对Java基础集合的部分,对一些常见的问题进行整理,方便后续能够随时复习

二、问题与回答  

(1)Java集合类ArrayList初始化时数组的默认长度是多少?

答:在new ArrayList() 这段代码执行完后,实际上初始化时的数组的长度是一个空数组,也就是长度为0,我们可以看到源码

DEFAULTCAPACITY_EMPTY_ELEMENTDATA 为一个空数组

只有在执行add方法的时候,才会进行数组长度的初始化,初始化长度为10

(2)ArrayList扩容时扩容多少倍?扩容后是用原来的数组还是新的数组?

答:我们来看源码,扩容的算法是新长度 = 原有长度 + 原有长度 右移运算(10 +  10 >> 1 = 15),有小伙伴可能不清楚右移运算,实际上可以看成整除运算10/2,得到5,所以大概是扩容1.5倍

java.util.ArrayList#grow

第二个问题,扩容后是使用新数组,用的是Arrays.copyOf(elementData, newCapacity)方法,实际上底层用的是System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength))本地方法

(3)ArrayList是一个线程安全的集合类吗?

答:不是,arraylist的add、remove方法从源码上看都没加锁,所以不是线程安全的集合类

(4)判断一个集合类是否为线程安全的机制是什么?

答:这个从我个人理解,有其他意见的小伙伴欢迎在评论区补充

1、集合的增删方法是否增加同步机制(锁机制)

2、通过合理的代码设计,例如Fail-Fast机制,不允许在对集合迭代的时候对集合进行修改前置检查

(5)结合源码说一下Fail-Fast机制

答:Java集合检测机制,Fail-Fast机制是对集合迭代遍历时如果对集合进行修改,则会提示ConcurrentModificationException,实现原理就是通过modCount和expectedModCount两个变量进行对比,如果不相等,则说明你同时对集合进行遍历以及修改,则提示异常.

expectedModCount:是迭代遍历之前则会赋值好,expectedModCount = modCount

modCount:集合增删,会进行加或者减

java.util.ArrayList.Itr#checkForComodification

(6)ArrayList和LinkedList的使用场景。

答:其实这个问题算是一个经典的问题,讲讲ArrayList和LinkedList的特点

ArrayList :  随机插入和删除需要移动数组,查询性能很高,时间复杂度0(1)

LinkedList :  顺序插入和删除只需要改变链表引用即可,查询性能相对低下,时间复杂度O(n/2)

这里说下个人理解

  • 如果你使用的场景是顺序插入和删除比较多,查询比较少,那么时候LinkedList较适合
  • 如果你使用的场景是查询比较多,那么ArrayList较适合
  • 如果随机插入和删除比较多,这个需酌情评估,因为ArrayList是要移动数组,而LinkedList则需要找到原有位置然后再进行插入,两者的性能都不太好
(7)HashMap的底层数据结构。

答:这个也是一个比较经典的问题,HashMap的底层结构是 动态数组 +  链表的结构

(8)HashMap的存储逻辑(put()函数)

答:

  • 通过key的hash函数,得到一个哈希值,同时经过异或运算,再进行与运算,确定数组的下标
  • 确定下标以后,那就看这个下标有没有给其他元素占据,有,就要加入链表,加入链表之前又要判断是否链表长度超过8,如果超过8又要进行转换为红黑树,没超过8就加入链表,使用尾插法
  • 如果确定下标以后,这个下标没有冲突,那就把数组的下标指到这个元素下面。
  • put完以后,还会判断hashMap存在的元素是否大于数组长度 * 扩容因子,如果大于就会进行扩容
(8)HashMap存储元素时key完全一样该怎么处理?

答:这个我们通过源码可以看到,value会进行覆盖

(9)HashMap的默认长度是多少?扩容是扩成几倍?

答:看完源码发现在在执行完new HashMap()的时候,实际上只是对一些变量进行初始化,并没有正在的创建动态数组和链表

只有等到put方法第一次执行才会进行动态数组的初始化,长度为16,扩容是2的幂次方,也就是32,64,128,256依次类推

(10)若两个key的hashcode值相同但equals不同,也就是说它们会插入到同一个桶里,新添加的节点是插入到已有元素的前面还是后面?

答:JDK1.7使用头插法,多线程场景下可能会出现循环链表,JDK1.8为了避免这种情况,使用尾插法,则会插入已有元素的后面。

(11)JDK 1.8的HashMap是否线程安全?

答:这个也是比较经典的问题,看源码会发现HashMap的put方法,remove方法没有任何的加锁机制,所以不是线程安全的。

(12)既然HashMap不是线程安全的类,有啥办法解决这个问题?

答:这里需要引出ConcurrentHashMap,它和hashMap的区别是线程安全的Map,底层是基于CAS操作 + synchronized关键字实现锁机制,保证多线程场景下不会出现问题。

(13)ConcurrentHashMap虽然是线程安全的,但它也存在什么问题?

答:从我个人的理解来看,有其他意见的小伙伴也欢迎在评论区补充

  • key不能为null
  • 因为增加了锁机制,性能会相对没有hashMap那么好
  • 复合操作的非原子性:‌ConcurrentHashMap虽然保证了基本的线程安全,‌但它并不能保证所有复合操作都是原子性的。‌例如,‌一个复合操作可能包括检查某个键是否存在(‌containsKey)‌和根据检查结果进行插入或更新(‌put)‌。‌这种由多个基本操作组成的复合操作不是原子性的,‌因此在多线程环境下可能会遇到竞态条件,‌导致数据不一致
(13)了解TreeMap吗?TreeMap最大的特点是什么?为什么已经有了HashMap了还要有TreeMap类?

答:TreeMap也是对Map的一种增强,它能够让Map的key按照某种规则进行排序,例如我们要实现排行榜,输出由多到少的排行情况,则可以接触TreeMap进行实现

三、总结

以上总结了关于集合相关的问题,后续遇到新的问题再进行补充,上面的问题都是自己通过对比其他博客的讲解以及梳理源码后进行解答,有着许多个人的理解在里面。这样理解会深刻一点

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2048805.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

类Unix环境在Windows上的演进史

自从以Unix为基础的操作系统被发明以来,尝试在Windows环境中模仿Unix操作的工具就一直存在。这种需求源于许多原因,包括Unix对脚本和命令行工具的强大支持,以及Unix和Linux系统在科学、工程和其他技术领域的广泛使用。下面就让我们一起探讨下…

input[type=checkbox]勾选框自定义样式

效果图&#xff1a; <template> <input class"rule-checkbox" type"checkbox" checked v-model"isChecked" /> </template><script setup lang"ts"> import { ref } from vue; const isChecked ref(); </…

应急响应-DDOS-技术指南

初步预判 通常&#xff0c;可从以下几方面判断服务器/主机是否遭受DDoS攻击查看防火墙、流量监控设备、网络设备等是否出现安全告警或大量异常数据包。如图所示&#xff0c;通过流量对比&#xff0c;发现在异常时间段存在大量UDP数据包&#xff0c;并且与业务无关。 通过安全设…

猫毛还是满天飞?宠物空气净化器是个好帮手

家里养了几只可爱的小猫咪&#xff0c;每天都想它们贴贴&#xff0c;有时候看到它们这么可爱的待在家里&#xff0c;都不想出门上班了。每天睁眼是它们&#xff0c;闭眼前也是它们&#xff0c;只要我待在家里&#xff0c;它们就和我一起挪动&#xff0c;好像身边多了几只可爱的…

qt-12工具盒(ToolBox)

工具盒--ToolBox drawer.hdrawer.cppmain.cpp运行图 drawer.h #ifndef DRAWER_H #define DRAWER_H #include <QWidget> #include <QToolBox> #include <QToolButton> #include <QGroupBox> #include <QVBoxLayout>class Drawer : public QToolB…

机械学习—零基础学习日志(如何理解线性代数5)

零基础为了学人工智能&#xff0c;正在快乐学习&#xff0c;每天都长脑子 特征向量和特征值 我们知道&#xff0c;线性映射&#xff0c;也就是矩阵&#xff0c;其实就是平面的一种变换。 但是在矩阵变换过程中&#xff0c;我们会发现有一个方向上&#xff0c;变化方向会与x的…

Python 函数式编程 内置高阶函数及周边【进阶篇 3】推荐

前面我们已经总结并实践了用python获取到了数据。也介绍了python中http网络请求的几种方式&#xff0c;正在学习python开发语言或者对python3知识点生疏需要回顾的请点这里 &#xff0c;本章主要总结了函数式编程及特点 和 python中内置的高阶函数及周边知识&#xff0c;方便自…

Scout Suite:开源云安全审计工具

Scout Suite 是一个开源、多云安全审计工具&#xff0c;旨在评估云环境的安全态势。 Scout Suite 利用云供应商提供的 API 来收集和整理配置数据&#xff0c;从而更轻松地识别潜在风险。 Scout Suite 无需手动筛选云 Web 控制台上的大量页面&#xff0c;而是会自动生成全面清…

ObjectUtils.nullSafeEquals你真的用对了吗?

目录 引言排查思考 引言 在写代码时&#xff0c;我们通常喜欢使用org.springframework.util.ObjectUtils#nullSafeEquals来比较两个对象是否相等&#xff0c;从而避免使用equals方法在对象为空时导致空指针异常。 最近在写代码时&#xff0c;我试图使用stream流的filter&#…

1.Linux_常识

UNIX、Linux、GNU 1、UNIX UNIX是一个分时操作系统&#xff0c;特点是多用户、多任务 实时操作系统&#xff1a;来了请求就去解决请求 分时操作系统&#xff1a;来了请求先存着&#xff0c;通过调度轮到执行时执行 2、Linux Linux是一个操作系统内核 发行版本&#xff1…

Linux - 常用基础指令和命令

文章目录 1、ifconfig指令2、ssh指令3、ls指令4、pwd命令5、cd 指令6、stat命令7、 touch指令8、mkdir指令9、rmdir指令10、rm指令11、man指令12、cp指令13、mv指令14、cat指令15、more指令16、less指令17、head指令18、tail指令19、时间相关的指令20、cal指令21、find指令22、…

指向派生类的基类指针、强转为 void* 再转为基类指针、此时调用虚函数会发生什么?

指向派生类的基类指针、强转为 void* 再转为基类指针、此时调用虚函数会发生什么&#xff1f; 1、无论指针类型怎么转&#xff0c;类对象内存没有发生任何变化&#xff0c;还是vfptr指向虚函数表&#xff0c;下面是成员变量&#xff0c;这在编译阶段就已经确定好了&#xff1b…

校园失物招领系统pf

TOC springboot337校园失物招领系统pf 绪论 1.1研究背景与意义 信息化管理模式是将行业中的工作流程由人工服务&#xff0c;逐渐转换为使用计算机技术的信息化管理服务。这种管理模式发展迅速&#xff0c;使用起来非常简单容易&#xff0c;用户甚至不用掌握相关的专业知识&…

自动驾驶-机器人-slam-定位面经和面试知识系列09之C++STL面试题(04)

这个博客系列会分为C STL-面经、常考公式推导和SLAM面经面试题等三个系列进行更新&#xff0c;基本涵盖了自己秋招历程被问过的面试内容&#xff08;除了实习和学校项目相关的具体细节&#xff09;。在知乎和牛客&#xff08;某些文章上会附上内推码&#xff09;也会同步更新&a…

鸿蒙(API 12 Beta3版)【HDR Vivid视频录制】 音视频编码

开发者可以调用本模块的Native API接口&#xff0c;实现在视频录制中支持HDR Vivid标准。 视频录制的主要流程是“相机采集 > 编码 > 封装成mp4文件”。 HDR Vivid视频编码 应用创建H265编码器&#xff0c;配置profile(main 10)相机底层包含HDR Vivid的surfacebuffer内…

Airtest 的使用

Airtest 介绍 Airtest Project 是网易游戏推出的一款自动化测试框架&#xff0c;其项目由以下几个部分构成 Airtest : 一个跨平台的&#xff0c;基于图像识别的 UI 自动化测试框架&#xff0c;适用于游戏和 App &#xff0c; 支持 Windows, Android 和 iOS 平台&#xff0c…

蛋白质基础

氨基酸:必需氨基酸 条件必需氨基酸和非必需氨基酸 必需氨基酸:机体需要但自身不能合成&#xff0c;必须从食物中获取的氨基酸。共有八种&#xff0c;对婴儿&#xff0c;组氨酸也是必需氨基酸。 条件必需氨基酸:半胱氨酸和酪氨酸在体内分别由蛋氨酸和苯丙氨酸转变而来。若膳食中…

HTML 列表和容器元素——WEB开发系列10

HTML 提供了多种方式来组织和展示内容&#xff0c;其中包括无序列表、有序列表、分区元素 ​​<div>​​ 和内联元素 ​​<span>​​、以及如何使用 ​​<div>​​​ 进行布局和表格布局。 一、HTML 列表 1. 无序列表 (​​<ul>​​) 无序列表用于展…

Java流程控制06:for循环详解

教学视频链接&#xff1a;https://www.bilibili.com/video/BV12J41137hu?p41&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5https://www.bilibili.com/video/BV12J41137hu?p41&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5 Java中的‌for循环结构‌是一种基础…

Python与DIAdem联合开发

Python可以通过COM接口与NI的DIAdem软件集成&#xff0c;允许用户以编程方式自动生成和定制报告。这种方式使得报告生成更加灵活且可定制&#xff0c;尤其适用于需要定期生成大量报告或对报告内容有特定要求的场景。 1. 工作原理 Python与DIAdem的集成主要依赖于COM&#xff0…