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

一、背景

针对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.rhkb.cn/news/404599.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软件测试基础入门

一、基础概念 什么是软件:控制计算机硬件的工具,操作系统软件、应用软件 软件基本组成:客户端、服务器、数据库 软件产生过程:需求构思--> 需求文档 -->UI/UE -- >产品研发 -->产品测试 -- >部署上线 什么是软…

web实现drag拖拽布局

这种拖拽布局功能其实在电脑操作系统或者桌面应用里面是经常使用的基础功能,只是有时候在进行web开发的时候,对这个功能需求量不够明显,但却是很好用,也很实用。能够让用户自己拖拽布局,方便查看某个区域更多内容&…

关于#vscode#的问题:把软件卸载不会再出现蓝屏

🏆本文收录于《CSDN问答解惑-专业版》专栏,主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收…

ViT篇外:NVIDIA Llama-3.1-Minitron 4B

相关阅读: ViT:3 Compact Architecture MobileLLM:“苗条”的模型比较好! 大家也许会很好奇为什么在ViT章节插入了NVIDIA Llama-3.1-Minitron 4B,ViT因为应用场景的特殊性所以都寄希望于高效率的模型,因…

搭建内网开发环境(二)|Nexus安装及使用

引言 上一篇教程中按照了 docker 作为容器化工具,在本篇教程中将使用 docker-compose 安装 nexus。 搭建内网开发环境(一)|基于docker快速部署开发环境 什么是 Nexus Nexus是一个强大的仓库管理器,主要用于搭建和管…

【论文阅读】SegNeXt:重新思考卷积注意力设计

《SegNeXt: Rethinking Convolutional Attention Design for Semantic Segmentation》 原文:https://github.com/Visual-Attention-Network/SegNeXt/blob/main/resources/paper.pdf 源码:https://github.com/Visual-Attention-Network/SegNeXt 1、简介 …

Apache Doris 中Compaction问题分析和典型案例

说明 此文档主要说明一些常见compaction问题的排查思路和临时处理手段。这些问题包括 Compaction socre高Compaction失败compaction占用资源多Compaction core 如果问题紧急,可联系社区同学处理 如果阅读中有问题,可以反馈给社区同学。 1 compaction …

微服务实战系列之玩转Docker(十一)

前言 在云原生的世界,经过十多年的进化,Docker已经形成了较完备的“后勤”保障服务和建立了荣辱与共的“密友圈”。用一句话可以概括:“Docker走遍天下,Swarm功不可没”。 因此,我们需尽可能做到对Swarm有充分的认识…

大数据-85 Spark 集群 RDD创建 RDD-Action Key-Value RDD详解 RDD的文件输入输出

点一下关注吧!!!非常感谢!!持续更新!!! 目前已经更新到了: Hadoop(已更完) HDFS(已更完) MapReduce(已更完&…

【联想电脑】:使用拓展坞后转接HDMI,无法识别显示屏

项目场景: 作为一个嵌入式软件开发者,有两个外接屏幕,不足为奇。 但是在今天的使用电脑过程中,出现了接了一个拓展坞上面有HDMI接口,但是HDMI接口接上外接显示屏的时候电脑无法识别到,导致只有电脑直连的HD…

家用小型洗衣机哪款好用?精选内衣洗衣机多维度测评盘点

对于很多都市生活的小伙伴来说,有一台小巧玲珑、功能齐全的内衣洗衣机则成了我们的救星。它不仅方便快捷,还能保持衣物清洁和卫生。然而,市面上的内衣洗衣机品牌五花八门。哪一个最好用、质量又靠谱呢?为了给大家提供更准确的选购…

【FPGA数字信号处理】- 数字信号处理如何入门?

​数字信号处理(Digital Signal Processing,简称DSP)是一种利用计算机或专用数字硬件对信号进行处理的技术,在通信、音频、视频、雷达等领域发挥着越来越重要的作用,也是FPGA主要应用领域之一。 本文将详细介绍数字信…

YOLOv5改进 | 融合改进 | C3融合ContextGuided增强分割效果

秋招面试专栏推荐 :深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡 专栏目录: 《YOLOv5入门 改…

模糊控制——创建与添加自定义的隶属函数

关键字:模糊控制;隶属函数;Matlab。 系列文章目录 模糊控制——(一)理论基础 模糊控制——(二)设计流程 模糊控制——(三)模糊洗衣机 模糊控制——(四&#…

SQL— DDL语句学习【后端 9】

SQL— DDL语句学习 在数据管理的广阔领域中,SQL(Structured Query Language)作为操作关系型数据库的编程语言,扮演着举足轻重的角色。它不仅定义了操作所有关系型数据库的统一标准,还为我们提供了强大的工具来管理、查…

jenkins最佳实践(二):Pipeline流水线部署springCloud微服务项目

各位小伙伴们大家好呀,我是小金,本篇文章我们将介绍如何使用Pipeline流水线部署我们自己的微服务项目,之前没怎么搞过部署相关的,以至于构建流水线的过程中中也遇到了很多自己以前没有考虑过的问题,特写此篇&#xff0…

【Redis】数据类型详解及其应用场景

目录 Redis 常⻅数据类型预备知识基本全局命令小结 数据结构和内部编码单线程架构引出单线程模型为什么单线程还能这么快 Redis 常⻅数据类型 Redis 提供了 5 种数据结构,理解每种数据结构的特点对于 Redis 开发运维⾮常重要,同时掌握每种数据结构的常⻅…

Postman接口测试项目实战

第 1 章 什么是接口测试 1.1、为什么要进行接口测试 目前除了特别Low的公司外,开发都是前后端分离的,就是说前端有前端的工程师进行编码,后端有后端的工程师进行编码,前后端进行数据基本都是通过接口进行交互的。 1.2、接口测…

zookeeper源码分析之事务请求处理

一.参考 zookeeper启动和选举的源码分析参考之前的帖子. 二.源码 1.职责链模式. 每次经过的processor都是异步处理,加入当前processor的队列,然后新的线程从队列里面取出数据处理. PrepRequestProcessor 检查ACL权限,创建ChangeRecord. SyncRequest…

ArcGIS空间自相关Moran‘s I——探究人口空间格局的20年变迁

先了解什么是莫兰指数? 莫兰指数(Morans I)是一种用于衡量空间自相关性的统计量,即它可以帮助我们了解一个地理区域内的观测值是否彼此相关以及这种相关性的强度和方向。 莫兰指数分类: 全局莫兰指数 (Global Moran…