Interview系列 - 05 Java|Iterator迭代器|集合继承体系|Set List Map接口特性|List实现类区别
文章目录
- 01. 迭代器 Iterator 是什么?
- 02. 迭代器 Iterator 有什么特点?
- 03. 迭代器 Iterator 怎么使用?
- 04. 如何边遍历边移除 Collection 中的元素?
- 05. Iterator 和 ListIterator 有什么区别?
- 06. 数组和集合的区别?
- 07. 常见集合类的继承体系?
- 08. 常见集合类的特点?
- 09. 常见集合类的底层数据结构?
- 10. Collection 和 Collections 有什么区别?
- 11. List、Set、Map 之间的区别是什么?
- 12. 怎么确保一个集合不能被修改?
- 13. ArrayList 和 Vector 的区别?
- 14. ArrayList 和 LinkedList 的区别?
- 15. ArrayList,LinkedList,Vector的使用场景?
- 16. Array 和 ArrayList 有何区别?
- 17. 如何实现数组和 List 之间的转换?
01. 迭代器 Iterator 是什么?
Iterator则主要用于遍历Collection集合中的元素,Iterator对象也被称为迭代器。
02. 迭代器 Iterator 有什么特点?
Iterator 迭代器的特点是更加安全,它可以保证当使用Iterator迭代访问Collection集合元素时,Collection集合里的元素不能被改变,只有通过Iterator的remove方法删除上一次next方法返回的集合元素才可以;否则将会引发java.util.Concurrent ModificationException异常。
Iterator迭代器采用的是快速失败(fail-fast)机制,一旦在迭代过程中检测到该集合已经被修改(通常是程序中的其他线程修改),程序立即引发ConcurrentModificationException异常,这样可以避免共享资源而引发的潜在问题。
03. 迭代器 Iterator 怎么使用?
Iterator接口隐藏了各种Collection实现类的底层细节,向应用程序提供了遍历Collection集合元素的统一编程接口。

使用iterator()方法要求容器返回一个Iterator 对象:
(1) 当创建指向集合的 Iterator 对象后,指针指向第一个元素的上方,即指向一个空;
(2) 调用 hasNext() 方法:判断集合中是否还有元素;
(3) 调用 next() 方法:向下移动指针并返回指针指向的元素,如果指针指向的内存中没有元素,会报异常;
(4) 调用 remove() 方法:一般和next()方法一起用,用来删除next()方法返回的元素;
04. 如何边遍历边移除 Collection 中的元素?
① 《阿里巴巴编码规范》中的一条:不要在foreach循环里进行元素的remove/add操作,使用foreach循环进行删除则会抛出ConcurrentModificationException异常。
public class Main {public static void main(String[] args) {DepartmentMemberInput departmentMemberInput1 = new DepartmentMemberInput("张三","18767880909");DepartmentMemberInput departmentMemberInput2 = new DepartmentMemberInput("张四","18767880910");List<DepartmentMemberInput> list1 = new ArrayList<>();list1.add(departmentMemberInput1);list1.add(departmentMemberInput2);for (DepartmentMemberInput departmentMemberInput : list1) {if(departmentMemberInput.getName().equals("张三")){list1.remove(departmentMemberInput);}}}
}
执行结果:

② 不要在 iterator 遍历的过程中使用 list.remove() 方法:
public class Main {public static void main(String[] args) {DepartmentMemberInput departmentMemberInput1 = new DepartmentMemberInput("张三","18767880909");DepartmentMemberInput departmentMemberInput2 = new DepartmentMemberInput("张四","18767880910");List<DepartmentMemberInput> list1 = new ArrayList<>();list1.add(departmentMemberInput1);list1.add(departmentMemberInput2);for (Iterator iterator = list1.iterator(); iterator.hasNext();) {DepartmentMemberInput departmentMemberInput = (DepartmentMemberInput) iterator.next();if(departmentMemberInput.getName().equals("张三")){// 使用Iterator迭代过程中,不可修改集合元素,下面代码引发异常list1.remove(departmentMemberInput);}}}
}
public class IteratorErrorTest
{public static void main(String[] args){// 创建一个集合Collection books=new HashSet();books.add("轻量级Java EE企业应用实战");books.add("Java讲义");// 获取books集合对应的迭代器Iterator it=books.iterator();while(it.hasNext()){String book=(String)it.next();System.out.println(book);if (book.equals("疯狂Android讲义")){//使用Iterator迭代过程中,不可修改集合元素,下面代码引发异常books.remove(book);}}}
}
执行结果:

③ 推荐在 iterator 遍历的过程中使用iterator.remove() 方法:
public class Main {public static void main(String[] args) {DepartmentMemberInput departmentMemberInput1 = new DepartmentMemberInput("张三","18767880909");DepartmentMemberInput departmentMemberInput2 = new DepartmentMemberInput("张四","18767880910");List<DepartmentMemberInput> list1 = new ArrayList<>();list1.add(departmentMemberInput1);list1.add(departmentMemberInput2);for (Iterator iterator = list1.iterator(); iterator.hasNext();) {DepartmentMemberInput departmentMemberInput = (DepartmentMemberInput) iterator.next();if(departmentMemberInput.getName().equals("张三")){iterator.remove();}}}
}
05. Iterator 和 ListIterator 有什么区别?
(1) Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。
(2) Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。
(3) ListIterator实现了Iterator接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索引等等。
06. 数组和集合的区别?
数组元素既可以是基本类型的值,也可以是对象(实际上保存的是对象的引用变量);而集合里只能保存对象(实际上只是保存对象的引用变量,但通常习惯上认为集合里保存的是对象)。
07. 常见集合类的继承体系?
Java的集合类主要由两个接口派生而出:Collection和Map,Collection和Map是Java集合框架的根接口,这两个接口又包含了一些子接口或实现类。

Set和List接口是Collection接口派生的两个子接口,它们分别代表了无序集合和有序集合;Queue是Java提供的队列实现,有点类似于List。

08. 常见集合类的特点?


09. 常见集合类的底层数据结构?
| 集合实现类 | 集合底层数据结构 | 是否线程安全 |
|---|---|---|
| ArrayList | 数组 | 非线程安全 |
| LinkedList | 双向链表 | 非线程安全 |
| Vector | 数组 | 线程安全,效率较低,使用少 |
| HashSet | HashMap | 非线程安全 |
| TreeSet | TreeMap | 非线程安全 |
| HashMap | 哈希表 | 非线程安全 |
| HashTable | 哈希表 | 线程安全,所有的方法都有synchronized关键字,效率较低,使用少 |
| Properties | HashMap | 线程安全,key和value只能存储String字符串 |
| TreeMap | 红黑树 | 非线程安全 |
10. Collection 和 Collections 有什么区别?
Collection接口是List、Set和Queue接口的父接口,该接口里定义的方法既可用于操作Set集合,也可用于操作List和Queue集合。
Collections是一个操作Set、List和Map等集合的工具类,该工具类里提供了大量方法对集合元素进行排序、查询和修改等操作,还提供了将集合对象设置为不可变、对集合对象实现同步控制等方法。
常用集合框架中的实现类HashSet、TreeSet、ArrayList、ArrayDeque、LinkedList、HashMap和TreeMap都是线程不安全的。如果有多个线程访问它们,而且有超过一个的线程试图修改它们,则可能出现错误。Collections提供了多个synchronizedXxx()方法可以把它们包装成线程同步的集合。
public class SynchronizedTest{public static void main(String[] args){//下面程序创建了4个同步的集合对象Collection c=Collections.synchronizedCollection(new ArrayList());List list=Collections.synchronizedList(new ArrayList());Set s=Collections.synchronizedSet(new HashSet());Map m=Collections.synchronizedMap(new HashMap());}
}
11. List、Set、Map 之间的区别是什么?
List:一个有序(元素存入集合的顺序和取出的顺序一致)容器,元素可以重复,可以插入多个null元素,元素都有索引。常用的实现类有 ArrayList、LinkedList 和 Vector;
Set:一个无序(存入和取出顺序有可能不一致)容器,不可以存储重复元素,只允许存入一个null元素,必须保证元素唯一性。Set 接口常用实现类是 HashSet、LinkedHashSet 以及 TreeSet;
Map是一个键值对集合,存储键、值和之间的映射。 Key无序,唯一;value 不要求有序,允许重复。Map 的常用实现类:HashMap、TreeMap、HashTable、LinkedHashMap、ConcurrentHashMap;

12. 怎么确保一个集合不能被修改?
Collections提供了如下三类方法来返回一个不可变的集合:
(1) emptyXxx():返回一个空的、不可变的集合对象,此处的集合可以是List,Set,Map。
(2) singletonXxx():返回一个只包含指定对象(只有一个或一项元素)的、不可变的集合对象,此处的集合可以是List,Set,Map。
(3) unmodifiableXxx:返回指定集合对象的不可变视图,此处的集合可以是List,Set,Map。
上面三类方法的参数是原有的集合对象,返回值是该集合的“只读”版本。通过Collections提供的三类方法,可以生成“只读”的Collection或Map。
public class UnmodifiableTest{public static void main(String[] args){// 创建一个空的、不可改变的List对象List unmodifiableList=Collections.emptyList();// 创建一个只有一个元素,且不可改变的Set对象Set unmodifiableSet=Collections.singleton("Java讲义");// 创建一个普通的Map对象Map scores=new HashMap();scores.put("语文" , 80);scores.put("Java" , 82);//返回普通的Map对象对应的不可变版本Map unmodifiableMap=Collections.unmodifiableMap(scores);// 下面任意一行代码都将引发UnsupportedOperationException异常unmodifiableList.add("测试元素"); //①unmodifiableSet.add("测试元素"); //②unmodifiableMap.put("语文" , 90); //③}
}
13. ArrayList 和 Vector 的区别?
ArrayList 和 Vector 均是 List 有序集合接口的实现类,都提供按照位置进行定位、添加或者删除的操作。
ArrayList是线程不安全的,当多个线程访问同一个ArrayList集合时,如果有超过一个线程修改了ArrayList集合,则程序必须手动保证该集合的同步性;但Vector集合则是线程安全的,无须程序保证该集合的同步性。因为Vector是线程安全的,所以Vector的性能比ArrayList的性能要低。实际上,即使需要保证List集合线程安全,也同样不推荐使用Vector实现类。可以使用Collections工具类提供的 List list = Collections.synchronizedList(new LinkedList());
14. ArrayList 和 LinkedList 的区别?
LinkedList与ArrayList、ArrayDeque的实现机制完全不同,ArrayList、ArrayDeque内部以动态数组的形式来保存集合中的元素,因此随机访问集合元素时有较好的性能;LinkedList内部以链表的形式来保存集合中的元素,因此随机访问集合元素时性能较差,但在插入、删除元素时性能非常出色(只需改变指针所指的地址即可)。需要指出的是,虽然Vector也是以数组的形式来存储集合元素的,但因为它实现了线程同步功能,所以各方面性能都有所下降。除此之外,LinkedList还实现了Deque接口,因此它可以被当成双端队列来使用,自然也可以被当成“栈”来使用了。
15. ArrayList,LinkedList,Vector的使用场景?
如果需要遍历List集合元素,对于ArrayList、Vector集合,应该使用随机访问方法(get)来遍历集合元素,这样性能更好;对于LinkedList集合,则应该采用迭代器(Iterator)来遍历集合元素。
如果需要经常执行插入、删除操作来改变List集合的大小,则应该使用LinkedList集合,而不是ArrayList。使用ArrayList、Vector集合需要经常重新分配内部数组的大小,其时间开销常常是使用LinkedList的时间开销的几十倍,效果很差。
如果有多个线程需要同时访问List集合中的元素,可考虑使用Collections将集合包装成线程安全的集合。
16. Array 和 ArrayList 有何区别?
(1) Array可以包含基本类型和对象类型,ArrayList只能包含对象类型。
(2) Array大小是固定的,定义后就不可被改变,ArrayList的大小是可变的。
(3) ArrayList提供了更多的方法和特性,比如:addAll(),removeAll(),iterator()等 。
17. 如何实现数组和 List 之间的转换?
(1) List转为数组:
直接调用ArrayList中的toArray方法就可以实现,List接口中,toArray有两个重载的方法:
Object[] toArray();
<T> T[] toArray(T[] a);
可见toArray可以用无入参的方式调用,返回一个Object数组;也可以用指定返回类型的方式调用,返回一个指定类型的数组。
@Test
public void test() {List<Object> rawList = new ArrayList();rawList.add("0");rawList.add("1");String[] arr = rawList.toArray(new String[rawList.size()]);for(String each:arr) {System.out.println(each);}
}
(2) 数组转换为 List:
如果需要将数组转为List,只需要使用Arrays.asList方法即可。
@Test
public void t5() {String[] arr = {"a","b","c"};List<String> list = Arrays.asList(arr);list.forEach(x -> System.out.println(x));
}
相关文章:
Interview系列 - 05 Java|Iterator迭代器|集合继承体系|Set List Map接口特性|List实现类区别
文章目录01. 迭代器 Iterator 是什么?02. 迭代器 Iterator 有什么特点?03. 迭代器 Iterator 怎么使用?04. 如何边遍历边移除 Collection 中的元素?05. Iterator 和 ListIterator 有什么区别?06. 数组和集合的区别&…...
LeetCode 1769. 移动所有球到每个盒子所需的最小操作数
有 n 个盒子。给你一个长度为 n 的二进制字符串 boxes ,其中 boxes[i] 的值为 ‘0’ 表示第 i 个盒子是 空 的,而 boxes[i] 的值为 ‘1’ 表示盒子里有 一个 小球。 在一步操作中,你可以将 一个 小球从某个盒子移动到一个与之相邻的盒子中。…...
MKS SKIPR V1.0船长版(Voron 2.4 R2)配置简要笔记
第一次用MKS SKIPR V1.0,设置过程中,也不知道怎么回事,跟现有的资料有些出入。首先,基本的配置调试可以参考官方的使用说明。 MKS SKIPR V1.0 使用说明书 这个说明比较简单,很多深一点的东西没有提现,不过…...
90后,转行软件测试3年,从月入7000+到月入过万,整理出的这一万字经验分享。
周一发工资了,到手12857.65,美滋滋 今年是我毕业参加工作的第3年,工资终于来到5位数了。上一家公司月薪7000,实际拿到手就6450左右,感觉今年真的是元气满满啊,工资翻倍,良好的人生开端。 想起…...
Java之关于String字符串笔试面试重点
目录 一.关于字符串的常量池 1.关于字符串产生的三种方式 2.关于字符串的常量池 3.直接赋值法和new的方式产生对象的区别 二.关于intern方法 1.情况一(已经包含) 2.情况二(已经包含) 3.情况三(未包含) 4.情况四 三.关于字符串的不可变性 1.了解字符串的不可变性 2.Str…...
mdio协议
1. 简介 MDIO接口中有特定的术语定义总线上的各种设备,驱动MDIO总线的设备被定义为站管理实体(STA),而被MDC管理的目标设备称为可被MDIO管理的设备(MMD)。 STA初始化MDIO所有的通信,同时负责驱动…...
kubectl命令
kubectl命令是操作 Kubernetes 集群的最直接和最高效的途径。 1、kubectl自动补全 $ source <(kubectl completion bash) # setup autocomplete in bash, bash-completion package should be installed first. $ source <(kubectl completion zsh) # setup autocomple…...
题库-JAVASE01
文章目录1.JAVA开发环境2.JAVA变量3.JAVA基本类型4.运算符和表达式5.分支结构6.循环结构7.数组8.方法1.JAVA开发环境 (单选题)在Java中,以下描述错误的是( ) A…class是源文件 B…java是编译前的源文件 C…class是编译后的文件 D.Java程序需…...
Java序列化机制
Java序列化机制 概述 java中的序列化可能都停留在实现Serializable接口上,对于它里面的一些核心机制没有深入了解过。直到最近在项目中踩了一个坑,就是序列化对象添加一个字段以后,使用方系统报了反序列化失败,原因是我们双方的…...
3款强大到离谱电脑软件,都是效率神器,从此远离加班
闲话少说,直接上狠货。 1、ImageGlass ImageGlass是一款值得吹爆的电脑图片浏览工具,使用极其方便,体积50M左右,非常小巧,功能却强大到离谱,ImageGlass打开图片的速度极快,实现快速不同图像间切…...
【项目】Vue3+TS CMS 登录模块搭建
💭💭 ✨:Vue3 TS 💟:东非不开森的主页 💜: keep going💜💜 🌸: 如有错误或不足之处,希望可以指正,非常感谢😉 Vue3TS一、…...
Java 8 的那些常见写法
前言 现在Java已经发展到Java19版本了,由于Java后面一些版本,就开始商用收费了,所以目前绝大多数公司的JDK版本都是采用的之前稳定且免费的1.8版本,也就是Java8,这个版本已经能满足几乎所有业务的需求开发了ÿ…...
PyQt5数据库开发1 4.3 QSqlTableModel 之 相关槽函数的实现(多图长文详解)
目录 一、打开数据库表 1. 写打开数据库的槽函数 2. 运行后发现数据库可以打开了 3. ODBC配通了,数据库还是打不开 4. 写在tableView上显示数据库表的函数 5. 运行后发现表可以显示了 6. 代码分析 7. 添加列名称 8. 根据内容调整列宽 9. 备注:…...
QT 设计一个串口调试工具,用一个工程就能轻松解决,外加虚拟串口工具模拟调试,在日常工作中可类比模块间通信,非常详细建议收藏
QT 串口调试工具第一节 虚拟串口工具安装第二节 QT创建一个基于QWidget的项目第三节 UI界面设计第三节 项目头文件widget.h第四节 项目实现文件widget.cpp第五节 main函数第六节 编译结果重点第七节 使用QT打包程序,不安装QT的电脑可使用第一节 虚拟串口工具安装 -…...
OpenSumi 是信创开发云的首选
原文作者:行云创新技术总监 邓冰寒 引言 随着云原生应用的日益普及,开发上云也逐步被越来越多的厂商和开发者接受,在这个赛道国内外有不少玩家,国外的 GitHub Codespaces、CodeSandbox,GitPod、亚马逊 Cloud9…...
JdbcTemplate常用方法解析
文章目录1.JdbcTemplate简介2.JdbcTemplate主要方法:3.常用方法介绍update()方法增删改query()查询方法1.JdbcTemplate简介 JdbcTemplate是Spring JDBC的核心类,借助该类提供的方法可以很方便的实现数据的增删改查。 Spring对数据库的操作在jdbc上面做…...
生物素标记试剂1869922-24-6,Alkyne-PEG3-Biotin PC,炔烃PEG3生物素PC
1、试剂基团反应特点(Reagent group reaction characteristics):PC alkyne-PEG3-Biotin含一个炔烃和一个 PEG 链接的可光裂解生物素基团。含 3 个单元 PEG 的 ADC linker,生物素本身是个游离的小分子,在生物实验中常常…...
CS224W课程学习笔记(三):DeepWalk算法原理与说明
引言 什么是图嵌入? 图嵌入(Graph Embedding,也叫Network Embedding) 是一种将图数据(通常为高维稠密的矩阵)映射为低微稠密向量的过程,能够很好地解决图数据难以高效输入机器学习算法的问题。…...
rk3568 开发板Ubuntu系统说明
Ubuntu MinimalUbuntu Minimal系统基于Ubuntu 64bit系统构建,目前发布有Ubuntu18.04这个版本。与Ubuntu Desktop 相比具有以下特性:没有桌面环境,占用资源少,在简化网络管理之后,只需40M内存;针对嵌入式平台…...
Windows和Linux常用HASH算法使用命令
Windows和Linux常用hash算法使用命令 Windows,以文件xxx.zip为例 Windows 求文件 md5 certutil -hashfile xxx.zip md5Windows 求文件 sha1 certutil -hashfile xxx.zip sha1Windows 求文件 sha256 certutil -hashfile xxx.zip sha256Linux,以文件xxx.z…...
观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...
WebRTC调研
WebRTC是什么,为什么,如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...
[特殊字符] 手撸 Redis 互斥锁那些坑
📖 手撸 Redis 互斥锁那些坑 最近搞业务遇到高并发下同一个 key 的互斥操作,想实现分布式环境下的互斥锁。于是私下顺手手撸了个基于 Redis 的简单互斥锁,也顺便跟 Redisson 的 RLock 机制对比了下,记录一波,别踩我踩过…...
java+webstock
maven依赖 <dependency><groupId>org.java-websocket</groupId><artifactId>Java-WebSocket</artifactId><version>1.3.5</version></dependency><dependency><groupId>org.apache.tomcat.websocket</groupId&…...
免费批量Markdown转Word工具
免费批量Markdown转Word工具 一款简单易用的批量Markdown文档转换工具,支持将多个Markdown文件一键转换为Word文档。完全免费,无需安装,解压即用! 官方网站 访问官方展示页面了解更多信息:http://mutou888.com/pro…...
