Java集合常见面试题

1、Java集合概述

Java集合,也叫作容器。由两大接口派生而来:Collection接口,用于存放单一元素;Map接口,主要用于存放键值对。对于Collection接口,下面又有三个主要的子接口:List、Set、Queue

在这里插入图片描述

2、说说List,Set,Queue,Map的区别:

  • List:存储的元素是有序的,可重复的。
  • Set:存储的元素是无序的,不可重复的。
  • Queue:按特定的排队规则来确定先后顺序

3、如何选用集合?

根据集合的特点来选择合适的集合:

  • 我们需要根据键值获取到元素值时就选用Map接口下的集合 ,需要排序时选择TreeMap,不需要排序时就选择HashMap,需要保证线程安全就选用ConcurrentHashMap
  • 我们只需要存放元素值时,就选择实现Collection接口的集合,需要保证元素唯一时选择实现Set接口的集合比如TreeSet或HashSet,不需要就选择实现List的接口比如ArrayList或LinkedList,然后再根据实现这些接口的集合的特点来选用

4、为什么要使用集合?

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

5、List

ArrayList和Array(数组)的区别?

  • ArrayList内部基于动态数组实现,比Array(静态数组)使用起来更加灵活:
    • ArrayList会根据实际存储的元素动态地扩容和缩容,而Array被创建之后就不能改变它的长度
    • ArrayList允许使用泛型来确保类型安全,Array不可以
    • ArrayList中只能存储对象。对于基本类型数据,需要使用其对应的包装类(如Integer等)。Array可以直接存储基本类型数据,也可以存储对象。
    • ArrayList 支持插入、删除、遍历等常见操作,并且提供了丰富的API操作方法;Array只是一个固定长度的数组,只能按照下标访问其中的元素,不具备动态添加、删除元素的能力。
    • ArrayList创建时不需要指定大小,而Array创建时必须指定大小

ArrayList可以添加null值吗

  • ArrayList中可以存储任何类型的对象,包括null值。不过,不建议向ArrayList中添加null值,null值无意义,会让代码难以维护比如忘记做判空处理就会导致空指针异常。

ArrayList与LinkedList区别?

  • 是否保证线程安全:ArrayList和LinkedList都是不同步的,也就是不保证线程安全

  • 底层数据结构:ArrayList底层使用的是Object数组;LinkedList底层使用的是双向链表数据结构。

  • 插入和删除是否受元素位置的影响

    • ArrayList采用数组存储,插入和删除元素的时间复杂度受元素位置影响。
    • LinkedList采用链表存储,所以在头尾插入或者删除元素不受元素位置的影响。
  • 是否支持快速随机访问:LinkedList不支持高效的随机元素访问,而ArrayList(因为实现了RandomAccess接口)支持。快速随机访问就是通过元素的序号快速获取元素对象。

  • 内存空间占用:ArrayList的空间浪费主要体现在list列表的结尾会预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗比ArrayList更多的空间(因为要存放直接后继和直接前驱以及数据)

我们在项目中一般是不会使用到LinkedList的,需要用到LinkedList的场景几乎都可以使用ArrayList来代替,并且,性能通常会更好!

6、Set

无序性和不可重复性的含义是什么

  • 无序性不等于随机性。无序性是指存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的哈希值决定
  • 不可重复性是指添加的元素按照equals()判断时,返回false,需要同时重写equals()方法和hashCode()方法

比较HashSet、LinkedHashSet和TreeSet三者的异同

  • 三者都是Set接口的实现类,都能保证元素唯一,并且都不是线程安全的
  • 底层数据结构不同。HashSet的底层数据结构是哈希表(基于HashMap实现)。LinkedHashSet的底层数据结构是链表和哈希表,元素的插入和取出顺序满足FIFO。TreeSet底层数据结构是红黑树,元素是有序的,排序的方式有自然排序和定制排序。‘
  • 底层不同导致这三者的应用场景不同。HashSet用于不需要保证元素插入和取出顺序的场景,LinkedHashSet用于保证元素的插入和取出顺序满足FIFO的场景,TreeSet用于支持对元素自定义排序规则的场景。

7、Queue

Queue与Deque的区别

  • Queue是单端队列,只能从一端插入元素,另一端删除元素,实现上一般遵循FIFO原则
  • Deque是双端队列,在队列的两端均可以插入或删除元素。
  • Deque还提供有push()和pop()等其他方法,可用于模拟栈

ArrayDeque与LinkedList的区别

二者都实现了Deque接口,两者都具有队列的功能,区别如下:

  • ArrayDeque是基于可变长的数组和双指针来实现,而LinkedList则通过链表来实现
  • ArrayDeque不支持存储NULL数据,而LinkedList支持
  • ArrayDeque是在jdk1.6才被引入,而LinkedList早在jdk1.2时就已经存在
  • ArrayDeque插入时可能存在扩容过程,不过均摊后的插入操作依然为0(1)。虽然LinkedList不需要扩容,但是每次插入数据时均需要申请新的堆空间,均摊性能相比更慢。

从性能的角度上,选用ArrayDeque来实现队列要比LinkedList更好。此外,ArrayDeque也可以用于实现栈

说一说PriorityQueue

PriorityQueue是在JDK1.5中被引入,其与Queue的区别在于元素出队顺序是与优先级相关的,即总是优先级最高的元素先出队

什么是BlockingQueue

BlockingQueue(阻塞队列)是一个接口,继承自Queue。BlockingQueue阻塞的原因是其支持当队列没有元素时一直阻塞,直到有元素;还支持如果队列已满,一直等到队列可以放入新元素时再放入。

8、Map

HashMap和Hashtable的区别

  • 线程是否安全:HashMap是非线程安全的,Hashtable是线程安全的,因为Hashtable内部的方法基本都经过synchronized修饰。
  • 效率:因为线程安全的问题,HashMap要比Hashtable效率高一点。另外,Hashtable基本被淘汰,不要在代码中使用它
  • HashMap可以存储null的key和value,但null作为键只能有一个,null作为值可以有多个;Hashtable不允许有null键和null值,否则会抛出空指针异常
  • 底层数据结构:JDK1.8以后的HashMap在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树(将链表转换成红黑树前会判断,如果当前数组的长度小于64,那么会选择先进行数组扩容,而不是转换为红黑树),以减少搜索时间。Hashtable没有这样的机制

HashMap和TreeMap区别

TreeMap和HashMap都继承自AbstractMap,但是,TreeMap还实现了NavigableMap接口和SortedMap接口。实现NavigableMap接口让TreeMap有了对集合内元素的搜索的能力;实现SortedMap接口TreeMap有了对集合中的元素根据键排序的能力。默认是按Key的升序排序,不过我们也可以指定排序的比较器。

HashMap的底层实现

  • Jdk1.8之前,HashMap底层是数组和链表结合在一起使用也就是链表散列。HashMap通过key的hashcode经过扰动函数处理过后得到hash值,然后通过 (n-1)&hash 判断当前元素存放的位置(这里的n指的是数组的长度),如果当前位置存在元素的话,就判断该元素与要存入的元素的hash值以及key是否相同,如果相同的话,直接覆盖,不相同就通过拉链法解决冲突。
  • jdk1.8之后,相比于之前的版本,JDK1.8之后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树(将链表转换成红黑树前会判断,如果当前数组的长度小于64,那么会选择先进行数组扩容,而不是转换为红黑树),以减少搜索时间。

HashMap多线程操作导致死循环问题

JDK1.7及之前的HashMap在多线程环境下扩容操作可能存在死循环问题,这是由于当一个桶位中有多个元素需要进行扩容时,多个线程同时对链表进行操作,头插法可能会导致链表中的节点指向错误的位置,从而形成一个环形链表,进而使得查询元素的操作陷入死循环无法结束。为了解决这个问题,JDK1.8 版本的 HashMap 采用了尾插法而不是头插法来避免链表倒置,使得插入的节点永远都是放在链表的末尾,避免了链表中的环形结构。但是还是不建议在多线程下使用HashMap,因为多线程下使用HashMap还是会存在数据覆盖的问题。并发环境下,推荐使用ConcurrentHashMap

HashMap为什么线程不安全?

JDK1.7及之前版本,在多线程环境下,HashMap扩容时会造成死循环和数据丢失的问题。JDK1.8之后,在HashMap中,多个键值对可能会被分配到同一个桶(bucket),并以链表或红黑树的形式存储。多个线程对HashMap的Put操作会导致线程不安全,具体来说会有数据覆盖的风险。

HashMap常见的遍历方式

存在阻塞时parallelStream性能最高,非阻塞时parallelStream性能最低

HashMap 遍历从大的方向来说,可分为以下 4 类

  • 迭代器(Iterator)方式遍历;
  • For Each 方式遍历;
  • Lambda 表达式遍历(JDK 1.8+);
  • Streams API 遍历(JDK 1.8+)。

但每种类型下又有不同的实现方式,因此具体的遍历方式又可以分为以下 7 种:

  • 使用迭代器(Iterator)EntrySet 的方式进行遍历;
  • 使用迭代器(Iterator)KeySet 的方式进行遍历;
  • 使用 For Each EntrySet 的方式进行遍历;
  • 使用 For Each KeySet 的方式进行遍历;
  • 使用 Lambda 表达式的方式进行遍历;
  • 使用 Streams API 单线程的方式进行遍历;
  • 使用 Streams API 多线程的方式进行遍历。

ConcurrentHashMap线程安全的具体实现方式/底层具体实现

Java8中,ConcurrentHashMap取消了Segment分段锁,采用Node+CAS+synchronized来保证并发安全。数据结构跟HashMap1.8的结构类似,数组+链表/红黑二叉树。Java 8 在链表长度超过一定阈值(8)时将链表(寻址时间复杂度为 O(N))转换为红黑树(寻址时间复杂度为 O(log(N)))。

Java8中,锁粒度更细,synchronized只锁定当前链表或红黑二叉树的首节点,这样只要hash不冲突,就不会产生并发,就不会影响其他Node的读写,效率大幅提升。

9、Java集合使用注意事项总结

集合判空

判断所有集合内部的元素是否为空,使用isEmpty()方法,而不是size()==0的方式

因为isEmpty()方法的可读性更好,并且时间复杂度为O(1)

集合转Map

在使用 java.util.stream.Collectors 类的 toMap() 方法转为 Map 集合时,一定要注意当 value 为 null 时会抛 NPE 异常。

集合遍历

不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator 方式,如果并发操作,需要对 Iterator 对象加锁。

集合去重

可以利用 Set 元素唯一的特性,可以快速对一个集合进行去重操作,避免使用 List 的 contains() 进行遍历去重或者判断包含操作。

集合转数组

使用集合转数组的方法,必须使用集合的 toArray(T[] array),传入的是类型完全一致、长度为 0 的空数组。

数组转集合

使用工具类Array.aslist()把数组转换成集合时,不能使用其修改集合相关的方法,它的add/remove/clear方法会抛出UnsupportedOperationException异常

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CRM系统本地部署和云部署的优缺点

众所周知,CRM系统部署方式有两种,分别是本地部署和云部署。两者各有优缺点,企业可以按照自身的需求来进行选择。下面说说CRM不同部署方式的优缺点。 CRM本地部署 本地部署是指将CRM系统安装在企业自己的服务器上,并由企业自行维…

视频怎么转化为mp3,5种高效方法任选

视频怎么转化为mp3呢?想必这是我们工作过程中经常遇见的问题。众所周知,MP3格式是一种常见的音频格式,支持多种音频播放器和设备。通过将视频转换为MP3格式,用户可以方便地将视频的音频部分提取出来,保存为与视频大小不…

JS逆向 -- 某视频vurl值的加密分析

接上节课内容 JS逆向 -- 某视频vid值的加密分析 JS逆向 -- 某视频val值和pid值的加密分析 一、在上节课中有个vurl的值需要分析,具体内容如下 vurl: https://mp4play-hs-cdn.ysp.cctv.cn/o000017kuww.jbZe10002.mp4? sdtfrom4330701& guidlhsuf6ia_0rieucp…

以云原生推动代际跃升,2023通明湖论坛云原生分论坛召开

5月12日,由神州数码主办,北京经开区国家信创园、中关村云计算产业联盟协办的2023通明湖论坛-云原生分论坛在京召开。本次论坛,以“抓住云原生机遇,推动我国信息基础设施技术代际跃升”为主题,聚焦以云原生为核心引领的…

winform-SunnyUI控件解决大小位置变化

文章目录 前言问题种类使用SunnyUI解决控件DPI问题(分辨率问题)1.添加配置文件app.manifest2.将配置文件中dpiAware打开3.添加uiStyleManager1控件并将控件中DPIScale设置为true4.效果图 使用FlowLayOutPanel解决控件边距问题1.问题样式2.使用FlowLayOut…

推荐系统用户长序列建模

目录 一、背景 二、技术方案 2.1 DIN 简介 论文细节 优缺点 2.2 DINE 简介 论文细节 2.3 MIMN 简介 论文细节 2.4 SIM 简介 论文细节 优缺点 2.5 DSIN 简介 论文细节 一、背景 阿里巴巴的精排模型从传统lr,到深度学习,再到对用户长历…

Jmeter处理接口签名sign

写接口脚本的时候,很多接口涉及到签名,今天介绍下用Jmeter编写签名脚本的方法。 举个例子,开启红包接口,请求方式为post POST /v1/api/red/open json请求参数 { "red_id":1, "timestamp":"166703384…

iOS描述文件(.mobileprovision)一键申请

转载:iOS描述文件(.mobileprovision)一键申请 在主界面上点击描述文件按钮。 新建ios描述文件 然后点击新建,然后输入描述文件名称,描述文件名称字符和数字,自己好辨识就可以。然后选择描述文件类型,再选择bundle I…

Spring 拦截器

目录 今日良言:心若有所向往,何惧道阻且长 一、Spring 拦截器 1.拦截器简介 2.实现自定义拦截器 今日良言:心若有所向往,何惧道阻且长 一、Spring 拦截器 1.拦截器简介 Spring Boot 拦截器是面向切面编程-----AOP 的具体实现…

运动控制轴单位设置(H5U PLC)

H5U PLC运动控制相关应用,请参看下面博客文章 10轴总线控制(汇川H5UPLC+总线伺服编程应用)_RXXW_Dor的博客-CSDN博客H5UPLC控制总线伺服的详细配置过程,可以参看下面的文章链接:汇川H5U PLC通过EtherCAT总线控制SV660N和X3E伺服_ethercat总线伺服如何控制_RXXW_Dor的博客-C…

【K8s】openEuler23操作系统安装Docker和Kubernetes

openEuler23操作系统安装 服务器搭建环境随手记 文章目录 openEuler23操作系统安装前言:一、前期准备(所有节点)1.1所有节点,关闭防火墙规则,关闭selinux,关闭swap交换,打通所有服务器网络&am…

SQL语法

创建基本表 创建基本表要对表进行命名&#xff0c;定义表的每个列&#xff0c;定义表的完整性约束条件&#xff0c;我们使用CREATE TABLE语句创建基本表 CREATE TABLE <表名> (<列名> <数据类型> [DEEAULT<缺省值>] [列级约束定义], <列名> &l…

Netty实战(一)

Nett的概念及体系结构 第一章 Java网络编程1.1 Java NIO1.2 选择器 第二章 Netty是什么2.1 Netty简介2.2 Netty的特性2.2.1 设计2.2.2 易于使用2.2.3 性能2.2.4 健壮性2.2.5 安全性2.2.6 社区驱动 2.3 Netty的使用者2.4 异步和事件驱动2.4.1 异步2.4.2 异步和伸缩性 第三章 Net…

Qt文件系统源码分析—第一篇QFile

深度 本文主要分析Windows平台&#xff0c;Mac、Linux暂不涉及 本文只分析到Win32 API/Windows Com组件/STL库函数层次&#xff0c;再下层代码不做探究 本文QT版本5.15.2 类关系图 QTemporaryFile继承QFile QFile、QSaveFile继承QFileDevice QFileDevice继承QIODevice QIODev…

LayerZero有何发展潜力?空投热潮和大额融资双重加持

前言 近期Arbitrum的如愿空投再次点燃了市场「刷空投」的热情&#xff0c;除了ZK系的zkSync、Starknet及Scroll&#xff0c;也有部分用户将注意力投向了估值30亿美元的LayerZero。而 LayerZero刚刚完成的1.2亿美元B轮融资也让其市场热度持续攀升&#xff0c;在「空投热潮」及「…

华为OD机试真题 Java 实现【数字加减游戏】【2023Q1 200分】

一、题目描述 小明在玩一个数字加减游戏&#xff0c;只使用加法或者减法&#xff0c;将一个数字s变成数字t。 每个回合&#xff0c;小明可以用当前的数字加上或减去一个数字。 现在有两种数字可以用来加减&#xff0c;分别为a&#xff0c;其中b没有使用次数限制。 请问小明…

dwg格式转换pdf,教大家几个简单方法

dwg格式转换pdf&#xff0c;今天教大家几个简单方法吧。因为有很多小伙伴私信小编&#xff0c;询问关于CAD格式转换的问题。我们知道&#xff0c;dwg是CAD格式的一种&#xff0c;只能使用CAD软件进行打开&#xff0c;这非常不方便。特别是在需要在手机或其他平台查看时&#xf…

第12章:视图

一、视图 1.常见的数据库对象 ①表table&#xff1a;表是存储数据的逻辑单元&#xff0c;行和列形式存在。列是字段&#xff0c;行是记录。 ②数据字典&#xff1a;系统表&#xff0c;存放数据库相关信息的表。系统表的数据通常是数据库系统维护。 ③约束constraint&#x…

PPT背景图片怎么设置?4个详细教程在这!

案例&#xff1a;PPT背景图片怎么设置&#xff1f; 【因为论文答辩&#xff0c;最近需要制作PPT&#xff0c;昨晚之后感觉有点单调&#xff0c;我想设置一个背景图片&#xff0c;让我的PPT看起来更有风格&#xff0c;请问大家是怎么设置PPT背景图片的呢&#xff1f;】 PPT背景…

软件测试技术课程:软件测试流程

软件测试流程如下&#xff1a; 测试计划测试设计测试执行 单元测试集成测试确认测试系统测试验收测试回归测试验证活动 测试计划 测试计划由测试负责人来编写&#xff0c;用于确定各个测试阶段的目标和策略。这个过程将输出测试计划&#xff0c;明确要完成的测试活动&#x…