Java集合面试(上)
Java集合面试(上)
集合概述
Java 集合,也叫作容器,主要是由两大接口派生而来:一个是 Collection
接口,主要用于存放单一元素;另一个是 Map
接口,主要用于存放键值对
说说List,Set,Queue,Map的区别
- List:存储的元素是有序的,可重复
- Set:存的元素不可重复
- Queue:按照特定的规则排序,可重复
- Map:存键值对,key和value无序,key不可重复
集合框架底层数据结构
List
- ArrayList:
Object[]
数组 Vector
:Object[]
数组。LinkedList
:双向链表
Set
- HashSet:基于
HashMap
实现的 - LinkedHashSet:
LinkedHashMap
来实现的 - TreeSet:红黑树
queue
PriorityQueue
:Object[]
数组来实现小顶堆- DelayQueue
:
PriorityQueue ArrayDeque
: 可扩容动态双向数组。
Map
- LinkedHashMap:基于拉链式散列结构即由数组和链表或红黑树组成
Hashtable
:数组+链表组成的TreeMap
:红黑树HashMap
:JDK1.8 之前HashMap
由数组+链表组成的,数组是HashMap
的主体,链表则是主要为了解决哈希冲突而存在的
怎么选用集合
- 我们需要根据键值获取到元素值时就选用
Map
接口下的集合,需要排序时选择TreeMap
,不需要排序时就选择HashMap
,需要保证线程安全就选用ConcurrentHashMap
。 - 我们只需要存放元素值时,就选择实现
Collection
接口的集合,需要保证元素唯一时选择实现Set
接口的集合比如TreeSet
或HashSet
,不需要就选择实现List
接口的比如ArrayList
或LinkedList
,然后再根据实现这些接口的集合的特点来选用
为什么要使用集合
Java 集合的优势在于它们的大小可变、支持泛型、具有内建算法等
List
ArrayList和Array(数组)的区别
- 集合可以进行动态扩容或者缩容,数组被创建就不能改变了
- 集合可以用泛型来保证类型安全,数组不行
- 集合只能存对象,基本类型只能存对应包装类,数组可以存对象和基本数据类型
- 集合支持插入删除遍历等操作,还有很多api但是数组只能通过下标访问元素,不具备动态添加删除元素的能力
- 集合创建不需要指定大小,而数组需要
ArrayList可以添加null值吗
ArrayList
中可以存储任何类型的对象,包括 null
值
ArrayList插入和删除元素的时间复杂度?
插入:
- 头部插入O(n),因为所有元素向后移动一个位置
- 尾部插入:没到容量时是O(1),到了是O(n),执行一次O(n)操作复制到新数组,在执行O(1)
- 指定位置插入:需要将目标位置之后的所有元素都向后移动一个位置,然后再把新元素放入指定位置O(n)
删除:
- 头部删除:由于需要将所有元素依次向前移动一个位置,因此时间复杂度是 O(n)。
- 尾部删除:当删除的元素位于列表末尾时,时间复杂度为 O(1)。
- 指定位置删除:需要将目标元素之后的所有元素向前移动一个位置以填补被删除的空白位置,因此需要移动平均 n/2 个元素,时间复杂度为 O(n)。
LinkedList为什么不能实现RandomAccess接口?
RandomAccess
是一个标记接口,用来表明实现该接口的类支持随机访问(即可以通过索引快速访问元素)但是它底层数据结构是链表,内存地址不连续,只能通过指针来定位,不支持随机快速访问
ArrayList和LinkedList的区别
- 都不保证线程安全
- 数据结构:一个数组一个双向链表
- 插入和删除受元素位置影响
- 是否支持快速随机访问:ArrayList支持
- 内存空间占用:
ArrayList
的空间浪费主要体现在在 list 列表的结尾会预留一定的容量空间,而 LinkedList 的空间花费则体现在它的每一个元素都需要消耗比 ArrayList 更多的空间(因为要存放直接后继和直接前驱以及数据)。
我们在项目中一般是不会使用到 LinkedList
的,需要用到 LinkedList
的场景几乎都可以使用 ArrayList
来代替,并且,性能通常会更好!
ArrayList扩容机制
Set
Comparable 接口和 Comparator区别
Comparable
接口用于定义对象自身的比较逻辑。当一个类实现了Comparable
接口,它就表明该类的对象能够自然地相互比较,并且这种比较是基于对象本身的属性Comparator
接口用于定义外部比较逻辑,即一个类的对象可以通过外部比较器来决定排序顺序。这使得即使是在不修改对象自身的情况下,也可以根据不同的标准对对象进行排序。
无序性和不可重复性
- 无序性:不是随机性,只是没有按照数组索引顺序去添加,而是根据哈希值决定
- 不可重复性:就是equals返回false
HashSet和LinkedHasSet和TreeSet的区别?
- 三者线程不安全
- 底层数据结构不同
- 应用场景不同。HashSet用在不用保证顺序的场景,LinkedHashSet(链表哈希表)保证了FIFO(先进先出),TreeSet用于自定义顺序
Queue
Queue和Deque的区别
Queue
是单端队列,只能从一端插入元素,另一端删除元素,实现上一般遵循 先进先出(FIFO) 规则。
Queue
扩展了 Collection
的接口,根据 因为容量问题而导致操作失败后处理方式的不同 可以分为两类方法: 一种在操作失败后会抛出异常,另一种则会返回特殊值。
Queue 接口 | 抛出异常 | 返回特殊值 |
---|---|---|
插入队尾 | add(E e) | offer(E e) |
删除队首 | remove() | poll() |
查询队首元素 | element() | peek() |
Deque
是双端队列,在队列的两端均可以插入或删除元素。
Deque
扩展了 Queue
的接口, 增加了在队首和队尾进行插入和删除的方法,同样根据失败后处理方式的不同分为两类:
Deque 接口 | 抛出异常 | 返回特殊值 |
---|---|---|
插入队首 | addFirst(E e) | offerFirst(E e) |
插入队尾 | addLast(E e) | offerLast(E e) |
删除队首 | removeFirst() | pollFirst() |
删除队尾 | removeLast() | pollLast() |
查询队首元素 | getFirst() | peekFirst() |
查询队尾元素 | getLast() | peekLast() |
ArrayDeque和
LinkedList的区别
两者都实现了Deque接口,具有队列的功能
-
底层结构:ArrayDeque是可变长数组加双指针,另外一个是链表
-
ArrayDeque
不支持存储NULL
数据,但LinkedList
支持。 -
ArrayDeque
是在 JDK1.6 才被引入的,而LinkedList
早在 JDK1.2 时就已经存在。 -
ArrayDeque
插入时可能存在扩容过程, 不过均摊后的插入操作依然为 O(1)。虽然LinkedList
不需要扩容,但是每次插入数据时均需要申请新的堆空间,均摊性能相比更慢。
从性能的角度上,选用 ArrayDeque
来实现队列要比 LinkedList
更好。此外,ArrayDeque
也可以用于实现栈。
PriorityQueue
PriorityQueue
是在 JDK1.5 中被引入的, 其与 Queue
的区别在于元素出队顺序是与优先级相关的,即总是优先级最高的元素先出队。
这里列举其相关的一些要点:
PriorityQueue
利用了二叉堆的数据结构来实现的,底层使用可变长的数组来存储数据PriorityQueue
通过堆元素的上浮和下沉,实现了在 O(logn) 的时间复杂度内插入元素和删除堆顶元素。PriorityQueue
是非线程安全的,且不支持存储NULL
和non-comparable
的对象。PriorityQueue
默认是小顶堆,但可以接收一个Comparator
作为构造参数,从而来自定义元素优先级的先后。
什么是BlockingQueue
BlockingQueue
(阻塞队列)是一个接口,继承自 Queue
。BlockingQueue
阻塞的原因是其支持当队列没有元素时一直阻塞,直到有元素;还支持如果队列已满,一直等到队列可以放入新元素时再放入。
BlockingQueue
常用于生产者-消费者模型中,生产者线程会向队列中添加数据,而消费者线程会从队列中取出数据进行处理。
ArrayBlockingQueue和
LinkedBlockingQueue区别
-
底层实现:
ArrayBlockingQueue
基于数组实现,而LinkedBlockingQueue
基于链表实现 -
是否有界:
ArrayBlockingQueue
是有界队列,必须在创建时指定容量大小。LinkedBlockingQueue
创建时可以不指定容量大小,默认是Integer.MAX_VALUE
,也就是无界的。但也可以指定队列大小,从而成为有界的。 -
锁是否分离:
ArrayBlockingQueue
中的锁是没有分离的,即生产和消费用的是同一个锁;LinkedBlockingQueue
中的锁是分离的,即生产用的是putLock
,消费是takeLock
,这样可以防止生产者和消费者线程之间的锁争夺。 -
内存占用:
ArrayBlockingQueue
需要提前分配数组内存,而LinkedBlockingQueue
则是动态分配链表节点内存。这意味着,ArrayBlockingQueue
在创建时就会占用一定的内存空间,且往往申请的内存比实际所用的内存更大,而LinkedBlockingQueue
则是根据元素的增加而逐渐占用内存空间
相关文章:
Java集合面试(上)
Java集合面试(上) 集合概述 Java 集合,也叫作容器,主要是由两大接口派生而来:一个是 Collection接口,主要用于存放单一元素;另一个是 Map 接口,主要用于存放键值对 说说List,Set,Queue&#…...

Python画笔案例-046 绘制小红伞
1、绘制小红伞 通过 python 的turtle 库绘制 小红伞,如下图: 2、实现代码 绘制 小红伞,以下为实现代码: """小红伞.py """ import turtledef draw_pattern():"""画填充圆弧"&…...
使用 .NET 6 构建跨平台 Worker Service 服务:跨越平台的 C# 服务开发——解决Windows服务跨平台问题
现代软件开发中,构建跨平台的应用程序变得愈加重要。C# 和 .NET 6 的出现使得在 Windows、Linux 和 macOS 上创建背景服务变得简单而高效。在本指南中,我们将通过创建一个使用 .NET 6 的 Worker Service 来展示如何实现跨平台后台服务。 项目概述 我们…...

terminator-gnome
gnome import os#启动节点指令变量 stere"ros2 launch stereo_c start.py" utils"ros2 launch task utils.launch.py" #tab标题 stere_title"stere_driver" utils_title"utils"#一个终端界面打开5个tab cmd1f"gnome-terminal --…...
7.测试用例设计方法 + Bug
一、正交实验法 1.使用场景 因果关系比较庞大的情况下,不太适合用因果图判定表,在这种情况下,一般会采用正交实验法。 2.例子: 字符属性设置(4个条件) 字体很多 字符样式很多 …...

uniapp小程序,使用腾讯地图获取定位
本篇文章分享一下在实际开发小程序时遇到的需要获取用户当前位置的问题,在小程序开发过程中经常使用到获取定位功能。uniapp官方也提供了相应的API供我们使用。 官网地址:uni.getLocation(OBJECT)) 官网获取位置的详细介绍这里就不再讲述了,大…...
Reactive 编程-Project Reactor
Reactive 编程与 Project Reactor Reactive 编程是一种编程范式,主要用于处理异步数据流。它旨在通过声明式的编程方式处理事件驱动的非阻塞任务,特别适合于构建响应式、可扩展、高并发的应用。随着互联网应用规模的扩大和响应速度的提升需求࿰…...

splice用法
天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…...

Redis - 缓存
文章目录 目录 文章目录 1. 什么是缓存? 2. 使用Redis作为缓存 2.1 关系型数据库的缺点 3. 缓存的更新策略 3.1 定期生成 3.2 实时生成 缓存淘汰策略 4. 缓存预热, 缓存穿透, 缓存雪崩 和 缓存击穿 缓存预热 缓存穿透 缓存雪崩 缓存击穿 总结 1. 什么…...

基于SpringBoot+Vue的养老院管理系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的…...
多线程爬虫接入代理IP:高效数据抓取的秘诀
在现代网络环境中,爬虫已经成为获取信息的利器。然而,随着网站反爬措施的不断升级,单线程爬虫往往无法满足需求。多线程爬虫与代理IP的结合,不仅能提高效率,还能有效规避IP封禁问题。本文将详细探讨多线程爬虫接入代理…...
[网络][CISCO]Cisco-PIX配置详解
Cisco PIX防火墙配置指南 任何企业安全策略的一个主要部分都是实现和维护防火墙,因此防火墙在网络安全的实现当中扮演着重要的角色。防火墙通常位于企业网络的边缘,使内部网络与Internet之间或与其他外部网络互相隔离,并限制网络互访&#x…...

拒绝千篇一律,AI帮你定制独一无二的个人写真
每个女人都渴望展现最美的自己,你是否厌倦了拍出千篇一律的照片?今天,我要告诉你一个秘密,用简单三步,即可打造属于你的独一无二个人写真!文生图、蒙版换脸、图生图,三步化身超级模特࿰…...
在云服务器上安装 RabbitMQ:从零到一的最佳实践
🛠 1. RabbitMQ 简介 RabbitMQ 是一个开源的消息代理中间件,广泛应用于高并发、异步任务队列的场景中。在分布式系统架构中,RabbitMQ 可以充当消息的中转站,帮助不同服务之间进行高效的消息通信。 在这篇文章中,我们…...

【nginx】搭配okhttp 配置反向代理
nginx的默认是一个反向代理。 nginx会默认把输入的请求,转向其他的服务器执行。 这些转向的服务器与客户端发起的服务器不是同一个。 客户端只认识nginx,不知道ngiix转向何方。 正向代理修改okhttp的proxy,实际上很多代理都是正向的。 反向代理修改请求路径到nginx。 感觉还…...

Android V 广播注册和配置注意事项问题
现象 在Android V平台上,应用注册非Protected广播时,如果没有加导出flag会抛出异常导致进程crash。 E/AndroidRuntime: FATAL EXCEPTION: main java.lang.SecurityException: com.demo.myapplication: One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORT…...

深入解读Docker核心原理:Namespace资源隔离机制详解
在容器技术中,资源隔离 是容器化能够实现轻量级虚拟化的关键技术之一。通过资源隔离,容器可以拥有自己的独立环境,确保容器之间互不干扰,从而实现应用的安全和稳定。Docker作为主流的容器平台,其核心的资源隔离机制依赖…...

学习通、智慧职教刷课脚本
🐐个人主页 可惜已不在 🐋可以分享给身边有需要的人🐶 🐉有用的话就留下一个三连吧😼 目录 一.安装 脚本运行器 篡改猴 - Microsoft Edge Addons 二.安装脚本 三.扩展 一.安装 脚本运行器 安装浏览器 Microsoft E…...

SEO写作:从实战到精进的全方位指南
在数字化浪潮中,SEO不再是简单的关键词堆砌,而是成为企业品牌建设与市场拓展的核心策略。作为一名深耕SEO领域的实践者,我深知其中的门道与奥秘。今天,我将结合过往实战经验,以独特视角,带你一窥SEO写作的精…...

解决 git 不是内部或外部命令,也不是可运行的程序
目录 报错提示: 一、解决办法 1、从git官网下载windows版本的git 2、安装 3、注意事项 二、报错 1、解决 fatal: Not a git repository (or any of the parent directories): .git 问题 报错提示: 一、解决办法 Windows下配置Git: 1…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...

三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...

Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...

数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !
我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...

Sklearn 机器学习 缺失值处理 获取填充失值的统计值
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...

基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)
引言 在嵌入式系统中,用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例,介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单,执行相应操作,并提供平滑的滚动动画效果。 本文设计了一个…...

LINUX编译vlc
下载 VideoLAN / VLC GitLab 选择最新的发布版本 准备 sudo apt install -y xcb bison sudo apt install -y autopoint sudo apt install -y autoconf automake libtool编译ffmpeg LINUX FFMPEG编译汇总(最简化)_底部的附件列表中】: ffmpeg - lzip…...