Java集合常见面试题

news2024/11/29 4:26:12

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异常

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

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

相关文章

桌面远程工具推荐

目前市面上的远程工具多如牛毛,很多人不知道怎么选择,下面小编介绍两种桌面远程工具,它们都是跨平台的,均支持Windows,Mac OS,IOS和安卓,分别是RayLink,VNC,好用&#xf…

eKuiper 源码解读:从一条 SQL 到流处理任务的旅程

概述 LF Edge eKuiper 是 Golang 实现的轻量级物联网边缘分析、流式处理开源软件,可以运行在各类资源受限的边缘设备上。eKuiper 的主要目标是在边缘端提供一个流媒体软件框架。其规则引擎允许用户提供基于SQL 或基于图形(类似于 Node-RED)的…

权威硬核认证|数说故事携手IDEA共创学术论文获NLP国际顶会 ACL 2023收录

日前,数说故事携手IDEA共创的学术论文——《A Unified One-Step Solution for Aspect Sentiment Quad Prediction (一个统一的单步情感四元组识别方法) 》被国际学术顶会 ACL 2023 接收为 Findings长文。这是继上一年IDEA数说故事实验室论文获「国际AI顶会IJCAI-ECA…

加密解密软件VMProtect教程(六):主窗口之控制面板“项目”部分(1)

VMProtect 是保护应用程序代码免遭分析和破解的可靠工具,但只有在正确构建应用程序内保护机制并且没有可能破坏整个保护的典型错误的情况下才能最有效地使用。 接下来为大家介绍关于VMProtect主窗口中的控制面板,其中包括:“项目”部分、“功…

AD20 原理图设计流程

Altium Designer 20 的原理图设计大致可以分为9个步骤: (1)新建原理图。这是原理图设计的第一步。 (2)图纸设置。图纸设置就是要设置图纸的大小,方向等信息。图纸设置要根据电路图的内容和标准化来进行。…

教你几分钟玩转.ipynb文件

找代码的时候最不喜欢遇到.ipynb文件,因为要打开jupyter,作为懒癌患者,即使电脑安装了jupyter也很少去用。不知道有没有人和我一样,真的很不喜欢在终端开一个程序,不能关的那种。 今天又遇到.ipynb文件,这…

我是如何利用midjourney制作表情包的

起初是在看到大厂文章《【Midjourney教程】设计麻瓜也能10分钟上架一套表情包》以后,才想自己试试的。如果你是midjourney的老鸟了,那么参照着文章,应该也能很顺利的完成。下面我介绍下,我遇到的问题和解决方案 准备:…

Tesseract.js离线识别图片中的文字

从官网下载Tesseract.js的离线版本 https://github.com/jeromewu/tesseract.js-offline 初始化 解压下载文件使用cmd命令行进入解压的文件夹(tesseract.js-offline-master),使用命令下载安装相关包npm install下载安装完成后,该…

看懂二维码识别OCR:从算法到API 接入代码

引言 二维码识别OCR(Optical Character Recognition)是结合了图像处理和OCR技术,以识别和提取二维码中的信息的技术,二维码识别OCR 可以实现对图像中的二维码进行自动检测和解码,并将其内容提取为可编辑的文本&#x…

腾讯云 Serverless Stable Diffusion 应用免费名额限量放送,试用申请开启!

近半年,AIGC 领域惊喜接踵而至。除了 Chatgpt,在AI绘图方面 Stable Diffusion 也大放异彩。网上的教程五花八门,有很多小伙伴根本不知如何下手,苦不堪言。 现在腾讯云 Serverless Stable Diffusion 应用免费名额限量放送&#xf…

阿里P6测试总监分享,这份《接口自动化测试》总结,让我成功入门接口自动化测试...

昨晚在某个测试交流群,听了一个测试老司机分享接口自动化测试的内容,对接口自动化有了更深的一些认识,也为接下来公司的接口自动化实施,提供了更多的思路。 这篇文章,就说说功能测试到接口自动化的进阶,以…

( 位运算 ) 318. 最大单词长度乘积 ——【Leetcode每日一题】

❓318. 最大单词长度乘积 难度:中等 给你一个字符串数组 words ,找出并返回 length(words[i]) * length(words[j]) 的最大值,并且这两个单词不含有公共字母。如果不存在这样的两个单词,返回 0 。 示例 1: 输入&…

sqlmap对dvwa靶场的账号密码进行破解

1.进行靶场搭建 准备两台虚拟机 靶机:win7 攻击机:kali linux win7IP 172.26.0.130kali linuxIP 172.26.0.129 虚拟机搭建好后,相互ping能ping同就行 安装xampp XAMPP Installers and Downloads for Apache FriendsXAMPP is an easy to install…

数字化赋能,探索智慧银行建设的最佳实践

导语 | 数字经济时代,数字化已成为银行业转型升级的战略手段。近年来,商业银行纷纷加大对信息科技的投入,数字化在改变银行业务模式的同时,更是构建起了数字金融新生态。今天,我们特邀腾讯云 TVP 行业大使、舜源科技合…

值传递、引用传递

​​​​​辟谣时间 错误理解一:值传递和引用传递,区分的条件是传递的内容,如果是个值,就是值传递。如果是个引用,就是引用传递。 错误理解二:Java是引用传递。 错误理解三:传递的参数如果是普通…

国内有哪些SAAS软件?SAAS软件有哪些优点?

国内有哪些SAAS软件?SAAS软件有哪些优点?不请自来答一下,通过SaaS软件与传统软件的对比来详细讲下SaaS软件有哪些优点? 配合以下内容食用更佳: 关于概念——深度详解什么是SaaS(软件即服务)关…

项目报告:turtle画小猪佩奇

目录 项目:一、项目思路二、项目实战1. 导入模块2. 创建画布3. 绘制鼻子4. 绘制猪头5. 绘制耳朵6. 绘制眼睛7. 绘制脸8. 绘制嘴9. 绘制身体10.绘制手11.绘制脚12.绘制尾巴 三、项目展示 总结: 项目: ​ 我们做的项目是小猪佩奇绘画的一个项目…

农场农庄偷菜卖菜h5多端流量主小程序开发

农场农庄偷菜卖菜h5多端流量主小程序开发 种菜,收菜,偷菜,卖菜)玩法。 功能:动态背包,动态排行榜,定时收获,广告组件接入,背景音乐,按钮点击声音接入&#x…

多线程概念,常用接口与多进程之间的比较

多线程概念,常用接口与多进程之间的比较 多线程概念与常用接口多线程概念与相对于线程的区别什么是多线程(概念)进程和线程的区别在Linux系统下,进程和线程的区别如下:多进程和多线程优缺点比较:在多任务处…

国产仪器 1612A无线信道仿真器

1612A无线信道仿真器是一款专门的无线信道仿真设备,可准确实时仿真复杂的无线信道特征,包含路径损耗、延迟、多径衰落以及噪声等,重现真实的信号传播环境,用于对比测试及反复测试,加快问题的发现及解决的过程。本产品突…