Java面试——集合篇

1.Java中常用的容器有哪些?

容器主要包括 Collection 和 Map 两种,Collection 存储着对象的集合,而 Map 存储着键值对(两个对象)的映射表。

如图:

面试官追问:说说集合有哪些类及他们各自的区别和特点?

  • Set(所有实现类都不支持重复的元素)
    • TreeSet 基于红黑树实现,支持有序性操作,例如根据一个范围查找元素的操作。但是查找效率不如 HashSet,HashSet 查找的时间复杂度为 O(1),TreeSet 则为 O(logN)。
    • HashSet 基于HashMap实现,HashSet 的每个元素实际上是 HashMap 的一个键,而对应的值(value)是一个固定的虚拟对象。支持快速查找,但不支持有序性操作。并且失去了元素的插入顺序信息,也就是说使用 Iterator 遍历 HashSet 得到的结果是不确定的。
    • LinkedHashSet 是 HashSet 的子类,并且其内部是通过 LinkedHashMap 来实现的。内部使用双向链表维护元素的插入顺序。
  • List
    • ArrayList 基于动态数组实现,支持随机访问。
    • Vector 和 ArrayList 类似,但它是线程安全的。
    • LinkedList 基于双向链表实现,只能顺序访问,但是可以快速地在链表中间插入和删除元素。不仅如此,LinkedList 还可以用作栈、队列和双向队列。
  • Queue
    • LinkedList 可以用它来实现双向队列。
    • PriorityQueue 基于堆结构实现,可以用它来实现优先队列。
    • ArrayQueue基于数组实现,可以用它实现双端队列,也可以作为栈。

面试官追问:说说Map有哪些类及他们各自的区别和特点?

  • TreeMap 基于红黑树实现。
  • HashMap 1.7基于数组+链表实现,1.8基于数组+链表+红黑树。链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突)。JDK1.8 以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间。
  • HashTable 和 HashMap 类似,但它是线程安全的,这意味着同一时刻多个线程可以同时写入 HashTable 并且不会导致数据不一致。它是遗留类,不应该去使用它。(现在可以使用 ConcurrentHashMap 来支持线程安全,并且 ConcurrentHashMap 的效率会更高(1.7 ConcurrentHashMap 引入了分段锁, 1.8 引入了红黑树)。)
  • LinkedHashMap继承自 HashMap。使用双向链表来维护元素的顺序,顺序为插入顺序或者最近最少使用(LRU)顺序。

2. Arraylist 和 LinkedList的区别?

  • ArrayList:底层是基于数组实现的,查找快,增删较慢LinkedList 不支持高效的随机元素访问,而 ArrayList 支持。快速随机访问就是通过元素的序号快速获取元素对象(对应于get(int index)方法)。
  • LinkedList:底层是基于链表实现的。确切的说是循环双向链表(JDK1.6之前是双向循环链表、JDK1.7之后取消了循环),查找慢、增删快。LinkedList链表由一系列表项连接而成,一个表项包含3个部分︰元素内容、前驱表和后驱表。因此内存空间占用比ArrayList 更多。

面试官追问:ArrayList的增删一定比LinkedList要慢吗?

不一定的。

  1. 如果增删都是在末尾来操作(每次调用的都是 remove() 和 add()),此时 ArrayList就不需要移动和复制数组来进行操作了。如果数据量有百万级的时,速度是会比 LinkedList 要快的。
  2. 如果删除操作的位置是在中间。由于LinkedList的消耗主要是在遍历上,ArrayList的消耗主要是在移动和复制上(底层调用的是arrayCopy()方法,是native方法)。LinkedList 的遍历速度是要慢于ArrayList的复制移动速度的。如果数据量有百万级的时,还是ArrayList要快。

3.ArrayList实现 RandomAccess接口有何作用?

查看源码我们发现实际上 RandomAccess 接口中什么都没有定义。

        从源码可以看出RandomAccess 接口只是一个标志接口,只要List集合实现这个接口,就能支持快速随机访问。通过查看Collections类中的binarySearch()方法,可以看出,判断List是否实现RandomAccess接口来实行indexedBinarySerach(list, key)或 iteratorBinarySerach(list, key)方法。再通过查看这两个方法的源码发现:实现RandomAccess接口的List集合采用一般的 for循环遍历,而未实现这接口则采用迭代器,即ArrayList 一般采用for循环遍历,而 LinkedList 一般采用迭代器遍历。

public static <T>
int binarySearch(List<? extends Comparable<? super T>> list, T key) {if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)return Collections.indexedBinarySearch(list, key);elsereturn Collections.iteratorBinarySearch(list, key);
}

面试官追问:为何LinkedList却没实现这个接口?

ArrayList 底层是数组,而 LinkedList 底层是链表。

数组天然支持随机访问,时间复杂度为 O(1),所以称为快速随机访问。链表需要遍历到特定位置才能访问特定位置的元素,时间复杂度为 O(n),所以不支持快速随机访问。

ArrayList 实现了 RandomAccess 接口,就表明了他具有快速随机访问功能。 RandomAccess 接口只是标识,并不是说 ArrayList 实现 RandomAccess 接口才具有快速随机访问功能的!


4.Vector 和 ArrayList 的区别?

他们两个都实现了List接口。底层数据结构都是数组。

不同的是:

  1. vector通过removeadd等方法加上synchronized关键字实现线程同步,所以是线程安全的。而ArrayList是线程不安全的
  2. 由于vector使用了synchronized进行加锁,所以性能不如ArrayList
  3. Vector 扩容时,如果未指定扩容递增值capacityIncrement,或该值不大于 0 时,每次扩容为原来的 2 倍,否则扩容量为capacityIncrement的值。ArrayList每次扩容为旧容量的1.5

5. ArrayList 的扩容机制?

第一种情况:list中第一次添加数据

1585c2a5193a4e44b6ea83fbdbebc371.png

这种情况下,因为DEFAULT_CAPACITY = 10; 默认初始的容量(CAPACITY)

所以minCapacity会被赋值为较大的那个,也就是10。所以这里需要扩容(minCapacity(10) - elementData.length(0) > 0)进入扩容方法。

而进入扩容方法以后,会走第一次初始化数组长度那个if判断。

第二种情况:添加数据,但不需要扩容

3212cc99a561493a9f091f9b236c0463.png

这种情况下,根本不会走到扩容方法。

第三种情况:本次添加数据又需要扩容了

d829a3a2608c4ef1abfefe61971bfc15.png

这种情况下,进入扩容方法以后,会扩容原来容量的1.5倍。最后还会进行数组拷贝,把原数组元素拷贝到,新增容量后的数组中!

总结:

  1. 当使用add方法的时候首先调用ensureCapacityInternal方法,传入 size+1进去,检查是否需要扩容

  2. 如果空数组DEFAULTCAPACITY_EMPTY_ELEMENTDATA,就初始化为默认大小10,获取“默认的容量”和要扩容的大小两者之间的最大值

  3. 和当前数组长度比较,如果 if (minCapacity - elementData.length > 0)执行grow扩容方法

  4. 将数组扩容为原来的1.5倍 int newCapacity = oldCapacity + (oldCapacity >> 1);

  5. 检查新容量是否大于最小需要容量,若还是小于最小需要容量,那么就把最小需要容量当作数组的新容量

  6. 再检查新容量newCapacity 是否超出了ArrayList所定义的最大容量,若超出了,则调用hugeCapacity()来比较minCapacity和 MAX_ARRAY_SIZE,如果minCapacity大于MAX_ARRAY_SIZE,则新容量则为Interger.MAX_VALUE,否则,新容量大小则为 MAX_ARRAY_SIZE(MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8

  7. ArrayList 中copy数组的核心就是System.arraycopy方法,将original数组的所有数据复制到copy数组中,这是一个本地方法


6.Array和ArrayList有何区别?

  • Array(就是数组)可以容纳基本类型和对象,而ArrayList(集合)只能容纳对象
  • Array是指定大小的,ArrayList 的容量是根据需求自动扩展
  • ArrayList提供了更多的方法和特性,比如:addAll(),removeAll(),iterator()等等

面试官追问:什么时候更适合使用Array?

  1. 如果列表的大小已经指定,大部分情况下是存储和遍历它们可以使用Array
  2. 对于基本类型数据,ArrayList 使用自动装箱来减少编码工作量;而当处理固定大小的基本数据类型的时候,这种方式相对比较慢,这时候应该使用Array
  3. 如果你要使用多维数组,使用[][]比 List更容易

7.comparable和comparator的区别?

  • comparable接口出自java.lang包,可以理解为一个内比较器,因为实现了comparable接口的类可以和自己比较,要和其他实现了Comparable接口类比较,可以使用compareTo(objectobj)方法。compareTo方法的返回值是int,有三种情况:
    1. 返回正整数(比较者大于被比较者)
    2. 返回0(比较者等于被比较者)
    3. 返回负整数(比较者小于被比较者)
  • comparator接口出自java.util包,它有一个compare(object obj1,object obj2)方法用来排序,返回值同样是int,有三种情况,和compareTo类似。

它们之间的区别:

  1. 很多包装类都实现了comparable接口,像Integer、string等。所以直接调用co1lections.sort()直接可以使用。如果对类里面自带的自然排序不满意,而又不能修改其源代码的情况下,使用comparator就比较合适。
  2. 此外使用comparator可以避免添加额外的代码与我们的目标类耦合,同时可以定义多种排序规则,这一点是comparable接口没法做到的
  3. 从灵活性和扩展性讲Comparator更优,故在面对自定义排序的需求时,可以优先考虑使用comparator接口。

详细讲解:面试官:元素排序Comparable和Comparator有什么区别?-CSDN博客


8.Collection和Collections有什么区别?

  • Collection:是最基本的集合接口,它提供了对集合对象进行基本操作的通用接口方法。一个Collection代表一组Object,即Collection的元素。它的直接继承接口有List,Set 和Queue。
  • Collections:是不属于Java的集合框架的,它是集合类的一个工具类此类不能被实例化服务于Java的Collection框架。它包含有关集合操作的静态多态方法,实现对各种集合的搜索、排序、线程安全等操作。

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

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

相关文章

Web+Mysql——MyBatis

MyBatis 目标 能够完成Mybatis代理方式查询数据能够理解Mybatis核心配置文件的配置 1&#xff0c;Mybatis 1.1 Mybatis概述 1.1.1 Mybatis概念 MyBatis 是一款优秀的持久层框架&#xff0c;用于简化 JDBC 开发 MyBatis 本是 Apache 的一个开源项目iBatis, 2010年这个项目由…

idea启动oom了解决

解决 Error:java: java.lang.OutOfMemoryError: WrappedJavaFileObject[org.jetbrains.jps.javac.InputFileObject[file:///D:/mingan/pb/backend/src/main/java/com/cy/backend/service/impl/StorageServiceImpl.java]]pos36199: WrappedJavaFileObject[org.jetbrains.jps.j…

nodejs 012:Babel(巴别塔)语言转换与代码兼容

这里写目录标题 安装 Babel配置presets配置&#xff1a;常见的 Babel Presetsplugins配置&#xff1a;以 plugin-transform-class-properties 的类中属性为例index.jsx Babel 是一个独立的 JavaScript 编译器&#xff0c;主要用于将现代 JavaScript 代码转换为旧版本的 JavaScr…

Jira Cloud涨价5%-20%,钉钉项目Teambition成优选替代

近日&#xff0c;Jira再次宣布涨价&#xff0c;Cloud版涨幅达到5%-20%&#xff0c;这一消息来源于Atlassian官方面向合作伙伴发布的2024年最新涨价通知。 Atlassian旗下核心产品&#xff0c;包括Jira、Confluence、JiraServiceManagement等的Cloud版本价格将有所提高&#xff…

使用k8s搭建mariadb+nginx+wordpress

前期准备 1.启动docker进程 2.拉取三个镜像 mariadb:latest wordpress:latest nginx:alpine 3.保存三个镜像 docker save -o wordpress.tar wordpress:latest 4.上传到其他的节点主机 scp wordpress.tar root 192.168.118.88:~ 5.切换到node01和node02两个节点上 ctr…

【最新华为OD机试E卷】报文响应时间(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)

🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 💻 ACM金牌🏅️团队 | 大厂实习经历 | 多年算法竞赛经历 ✨ 本系列打算持续跟新华为OD-E/D卷的多语言AC题解 🧩 大部分包含 Python / C / Javascript / Java / Cpp 多语言代码 👏 感谢大家的订阅➕ 和 喜欢�…

谷歌女高管被裁员,3份兼职越干越开心!55岁正是闯的年纪!

在职场的金字塔顶端&#xff0c;那些大龄女性高管正在面对一场无形却深刻的危机。曾经&#xff0c;她们凭借坚定的决心和无畏的勇气&#xff0c;在职场中披荆斩棘&#xff0c;闯出了一片天地。 现代职场的年轻化和技术更新正将她们逐渐推向边缘。裁员通知的突如其来&#xff0…

Leetcode面试经典150题-97.交错字符串

给定三个字符串 s1、s2、s3&#xff0c;请你帮忙验证 s3 是否是由 s1 和 s2 交错 组成的。 两个字符串 s 和 t 交错 的定义与过程如下&#xff0c;其中每个字符串都会被分割成若干 非空 子字符串 &#xff1a; s s1 s2 ... snt t1 t2 ... tm|n - m| < 1交错 是…

好的头戴式降噪耳机一定很贵吗?四款热门头戴耳机盘点及推荐!

在快节奏的现代生活中&#xff0c;噪音无处不在&#xff0c;它常常干扰着我们的工作、学习与休闲时光。而一款高性价比的降噪蓝牙耳机&#xff0c;就如同一个贴心的伙伴&#xff0c;能为我们营造出一片宁静的听觉空间。如今&#xff0c;耳机市场蓬勃发展&#xff0c;想要好的头…

第161天:安全开发-Python-红队项目漏扫调用API推送微信任务自动添加并启动

目录 案例一&#xff1a;Python-红队项目-Xray调用推送微信 案例二&#xff1a;Python-红队项目-Awvs 调用自动添加 案例三&#xff1a; Python-红队项目-SQLMAP 调用自动添加 案例一&#xff1a;Python-红队项目-Xray调用推送微信 首先本地测试调用api发送信息给微信 api…

面试复盘与 AI 大模型学习

面试相关 一、面试公司与岗位信息 面试公司&#xff1a;顺丰科技面试岗位&#xff1a;AI 方向产品经理工作地点&#xff1a;深圳面试结果&#xff1a;通过&#xff0c;但放弃了该 offer 二、面试过程 整体情况 整个暑期实习面试之旅包含三轮&#xff0c;其中两轮是专业面试…

OpenAI o1解决了Quiet-STaR的挑战吗?(下)

随着OpenAI o1近期的发布&#xff0c;业界讨论o1关联论文最多之一可能是早前这篇斯坦福大学和Notbad AI Inc的研究人员开发的Quiet-STaR&#xff0c;即让AI学会先安静的“思考”再“说话” &#xff0c;回想自己一年前对于这一领域的思考和探索&#xff0c;当初也将这篇论文进行…

选择Alluxio来解决AI模型训练场景数据访问的五大理由

在AI模型训练尤其是大模型领域&#xff0c;存储系统的性能和稳定性直接决定了模型训练、推理、部署任务的效率和成本。随着全球AI行业的爆发带来的数据规模的快速增长&#xff0c;如何高效管理和利用这些数据成为AI模型训练中的一大挑战。 AI模型训练场景面临的五大难题 1. 数…

Yolov8-pose关键点检测:一种新的自适应算法轻量级通道分割和变换(ALSS)模块,解决红外检测场景存在严重遮挡和重叠目标时的局限性

💡💡💡本文解决什么问题:红外检测场景存在严重遮挡和重叠目标时的局限性的问题点。 💡💡💡提出了一种新的自适应算法轻量级通道分割和变换(ALSS)模块。该模块采用自适应信道分裂策略优化特征提取,并集成信道变换机制增强信道间的信息交换。这改善了模糊特征的提…

小阿轩yx-SaltStack部署与应用基础

小阿轩yx-SaltStack部署与应用基础 前言 当今数字化时代&#xff0c;大规模 IT 系统的管理已经成为一个复杂而繁琐的任务。为了提高系统管理的效率和准确性&#xff0c;自动化工具成为各企业不可或缺的一部分。Saltstack 作为一款强大的自动化和配置管理工具&#xff0c;在业…

AI服务器是什么?为什么要用AI服务器?

AI服务器的定义 AI服务器是一种专门为人工智能应用设计的服务器&#xff0c;它采用异构形式的硬件架构&#xff0c;通常搭载GPU、FPGA、ASIC等加速芯片&#xff0c;利用CPU与加速芯片的组合来满足高吞吐量互联的需求&#xff0c;为自然语言处理、计算机视觉、机器学习等人工智…

巧用联合与枚举:解锁自定义类型的无限潜力

嘿嘿,家人们,今天咱们来详细剖析C语言中的联合与枚举,好啦,废话不多讲,开干! 目录 1.:联合体 1.1:联合体类型的声明 1.1.1:代码1 1.1.2:代码2(计算机联合体的大小) 1.1.3:代码3 1.2:联合体的特点 1.2.1:代码1 1.2.2:代码2 1.3:相同成员的结构体与联合体进行对比 1.3…

【SA8155P】AIS Camera相关内容的简单介绍

高通车载相机模块(AIS,Automotive lmage System)是专门针对车载系统特性而设计的一套车载视觉架构,可用于AVM、RVC、DMS等常见车载视频应用开发。车载Camera系统的图像大部分是给自动驾驶等使用,更多考虑的是远距离传输、多摄像头图像处理等场景。 本文仅对AIS Camera相关…

国庆头像制作教程,这几种方法轻松制作国庆头像

随着国庆佳节的临近&#xff0c;朋友圈里是不是已经开始弥漫着浓浓的节日气氛&#xff1f;想要让你的头像也加入这场盛宴&#xff0c;成为最吸睛的存在吗&#xff1f;别急&#xff0c;今天就为你揭秘4款超实用的头像制作神器&#xff0c;能够让你的头像显现出浓郁的国庆节气氛&…

竹云董事长董宁主持2024深商千人中秋晚会

9月13日&#xff0c;由深商会主办“湾区升明月&#xff0c;深商共此时”2024深商中秋千人晚会在洲际酒店隆重举行&#xff0c;TCL 集团、农商银行、资本运营集团、泸州老窖、中集车辆、三诺集团、雷曼光电、置富控股、顺络电子、北科生物、霖峰投资、中国南玻集团、兆驰股份、山…