【Java 问题】集合——List

news2024/11/27 7:44:15

List

  • 1.说说有哪些常见集合?
  • 2.ArrayList和LinkedList有什么区别?
  • 3.ArrayList的扩容机制了解吗?
  • 4.ArrayList怎么序列化的知道吗? 为什么用transient修饰数组?
  • 5.快速失败(fail-fast)和安全失败(fail-safe)了解吗?
  • 6.有哪几种实现ArrayList线程安全的方法?
  • 7.CopyOnWriteArrayList了解多少?

1.说说有哪些常见集合?

集合相关类和接口都在java.util中,主要分为3种:List(列表)、Map(映射)、Set(集)。

在这里插入图片描述
其中 Collection 是集合 List 、 Set 的父接口,它主要有两个子接口:

  • List :存储的元素有序,可重复。
  • Set :存储的元素无序,不可重复。

Map 是另外的接口,是键值对映射结构的集合。

2.ArrayList和LinkedList有什么区别?

(1)数据结构不同

  • ArrayList基于数组实现
  • LinkedList基于双向链表实现

在这里插入图片描述
(2) 多数情况下,ArrayList更利于查找,LinkedList更利于增删

  • ArrayList基于数组实现,get(int index)可以直接通过数组下标获取,时间复杂度是O(1);LinkedList基于链表实现,get(int index)需要遍历链表,时间复杂度是O(n);当然,get(E element)这种查找,两种集合都需要遍历,时间复杂度都是O(n)。
  • ArrayList增删如果是数组末尾的位置,直接插入或者删除就可以了,但是如果插入中间的位置,就需要把插入位置后的元素都向前或者向后移动,甚至还有可能触发扩容;双向链表的插入和删除只需要改变前驱节点、后继节点和插入节点的指向就行了,不需要移动元素。

在这里插入图片描述
在这里插入图片描述

注意,这个地方可能会出陷阱,LinkedList更利于增删更多是体现在平均步长上,不是体现在时间复杂度上,二者增删的时间复杂度都是O(n)

(3)是否支持随机访问

  • ArrayList基于数组,所以它可以根据下标查找,支持随机访问,当然,它也实现了RandmoAccess 接口,这个接口只是用来标识是否支持随机访问。
  • LinkedList基于链表,所以它没法根据序号直接获取元素,它没有实现RandmoAccess 接口,标记不支持随机访问。

(4)内存占用,ArrayList基于数组,是一块连续的内存空间,LinkedList基于链表,内存空间不连续,它们在空间占用上都有一些额外的消耗:

  • ArrayList是预先定义好的数组,可能会有空的内存空间,存在一定空间浪费
  • LinkedList每个节点,需要存储前驱和后继,所以每个节点会占用更多的空间

3.ArrayList的扩容机制了解吗?

ArrayList是基于数组的集合,数组的容量是在定义的时候确定的,如果数组满了,再插入,就会数组溢出。所以在插入时候,会先检查是否需要扩容,如果当前容量+1超过数组长度,就会进行扩容。

ArrayList的扩容是创建一个1.5倍的新数组,然后把原数组的值拷贝过去。

在这里插入图片描述

4.ArrayList怎么序列化的知道吗? 为什么用transient修饰数组?

ArrayList的序列化不太一样,它使用 transient 修饰存储元素的 elementData 的数组, transient 关键字的作用是让被修饰的成员属性不被序列化。

为什么最ArrayList不直接序列化元素数组呢?

出于效率的考虑,数组可能长度100,但实际只用了50,剩下的50不用其实不用序列化,这样可以提高序列化和反序列化的效率,还可以节省内存空间。

那ArrayList怎么序列化呢?

ArrayList通过两个方法readObject、writeObject自定义序列化和反序列化策略,实际直接使用两个流 ObjectOutputStream 和 ObjectInputStream 来进行序列化和反序列化。

5.快速失败(fail-fast)和安全失败(fail-safe)了解吗?

快速失败(fail—fast):快速失败是Java集合的一种错误检测机制

  • 在用迭代器遍历一个集合对象时,如果线程A遍历过程中,线程B对集合对象的内容进行了修改(增加、删除、修改),则会抛出Concurrent ModificationException。
  • 原理:迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个 modCount 变量。集合在被遍历期间如果内容发生变化,就会改变 modCount 的值。每当迭代器使用hashNext()/next()遍历下一个元素之前,都会检测modCount变量是否为expectedmodCount值,是的话就返回遍历;否则抛出异常,终止遍历。
  • 注意:这里异常的抛出条件是检测到 modCount!=expectedmodCount 这个条件。如果集合发生变化时修改modCount值刚好又设置为了expectedmodCount值,则异常不会抛出。因此,不能依赖于这个异常是否抛出而进行并发操作的编程,这个异常只建议用于检测并发修改的bug。
  • 场景:java.util包下的集合类都是快速失败的,不能在多线程下发生并发修改(迭代过程中被修改),比如ArrayList 类。

安全失败(fail—safe)

  • 采用安全失败机制的集合容器,在遍历时不是直接在集合内容上访问的,而是先复制原有集合内容,在拷贝的集合上进行遍历。
  • 原理:由于迭代时是对原集合的拷贝进行遍历,所以在遍历过程中对原集合所作的修改并不能被迭代器检测到,所以不会触发Concurrent ModificationException。
  • 缺点:基于拷贝内容的优点是避免了Concurrent Modification Exception,但同样地,迭代器并不能访问到修改后的内容,即:迭代器遍历的是开始遍历那一刻拿到的集合拷贝,在遍历期间原集合发生的修改迭代器是不知道的。
  • 场景:java.util.concurrent包下的容器都是安全失败,可以在多线程下并发使用,并发修改,比如CopyOnWriteArrayList类。

6.有哪几种实现ArrayList线程安全的方法?

fail-fast是一种可能触发的机制,实际上,ArrayList的线程安全仍然没有保证,一般,保证ArrayList的线程安全可以通过这些方案:

  • 使用 Vector 代替 ArrayList。(不推荐,Vector是一个历史遗留类)
  • 使用 Collections.synchronizedList 包装 ArrayList,然后操作包装后的 list。
  • 使用 CopyOnWriteArrayList 代替 ArrayList。
  • 在使用 ArrayList 时,应用程序通过同步机制去控制 ArrayList 的读写。

7.CopyOnWriteArrayList了解多少?

CopyOnWriteArrayList就是线程安全版本的ArrayList。

它的名字叫 CopyOnWrite ——写时复制,已经明示了它的原理。

CopyOnWriteArrayList采用了一种读写分离的并发策略。CopyOnWriteArrayList容器允许并发读,读操作是无锁的,性能较高。至于写操作,比如向容器中添加一个元素,则首先将当前容器复制一份,然后在新副本上执行写操作,结束之后再将原容器的引用指向新容器。

在这里插入图片描述

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

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

相关文章

XILINX MIG驱动

简介 框架图 本章节主要针对MIG读写做详细介绍,首先创建BLOCK DESIGN,工程连接如下图所示: MIG IP介绍 DATAMOVER的配置这里不再做介绍,结合上篇文章讲到DATAMOVER对BRAM进行读写操作,这里通过AXI桥再加一个MIG模块,MIG模块的配置和说明如下: 1、Clock Period:…

记录一个Ajax发送JSON数据的坑,后端RequestBody接收参数小细节?JSON对象和JSON字符串的区别?

上半部分主要介绍我实际出现的问题,最终下面会有总结。 起因:我想发送post请求的data,但是在浏览器中竟然被搞成了地址栏编码 如图前端发送的ajax请求数据 如图发送的请求体: 很明显是keyvalue这种形式,根本就不是…

浏览器动态移动的小球源码分享

浏览器动态移动的小球源码分享 <script>(function(a){var width100,height100,borderRadius100,circlefunction(){};circle.prototype{color:function(){let colour "#"Math.floor(Math.random()*255).toString(16)Math.floor(Math.random()*255).toString…

基于SpringBoot剧本杀管理系统 【附源码】

基于SpringBoot剧本杀管理系统 效果如下&#xff1a; 系统首页界面 系统注册页面 剧本信息详细页面 后台登录界面 管理员主界面 剧本信息界面 剧本预约界面 作者主界面 研究背景 随着现代社会生活节奏的加快&#xff0c;人们越来越渴望通过各种娱乐活动来释放压力和增进社交…

开源 Three.js 案例及入门教程

Three.js入门教程目录 章节1认识three.js与开发环境搭建,rar 章节2 Three.js开发入门与调试设置,rar 章节3 Geometry进阶详解.rar 章节4 详解材质与纹理.rar 章节5 纹理材质高级操作,rar 章节6 详解灯光与阴影.rar 章节7 精通粒子特效.rar 章节8 详解光线投射与物体交互…

内容营销:基于大模型的内容再利用

在这篇文章中&#xff0c;我将带你了解一个完整的自动化系统&#xff0c;该系统可帮助你将任何内容重新用于你想要的其他帖子。 输入的内容可以是任何东西&#xff1a;YouTube 视频链接、博客文章链接、大纲、推文、pdf 等…… 我将在本文末尾为你提供所有代码。 一步一步地…

基于SpringBoot+Vue+Uniapp的仓库点单小程序的详细设计和实现

2. 详细视频演示 文章底部名片&#xff0c;联系我获取更详细的演示视频 3. 论文参考 4. 项目运行截图 代码运行效果图 代码运行效果图 代码运行效果图 代码运行效果图代码运行效果图 代码运行效果图 5. 技术框架 5.1 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发…

毕业设计 | Ruff开发板 + 华为云IoT物联网平台,实现家中温度、湿度、二氧化碳、PM2.5、甲醛监控分析...

基于温湿度、空气质量传感器实现温度、湿度、二氧化碳、PM2.5、甲醛环境数据实时监测。 硬件清单 我们采用 Ruff 开发板&#xff0c;串口连接温湿度传感器 DHT11 和空气质量传感器 SDS011&#xff0c;每5分钟采集一次数据&#xff0c;通过MQTT协议发送到华为云 IoT 物联网平台&…

QRTCN区间预测 | Matlab实现QRTCN时间卷积神经网络分位数回归区间预测

区间预测 | Matlab实现QRTCN时间卷积神经网络分位数回归区间预测 目录 区间预测 | Matlab实现QRTCN时间卷积神经网络分位数回归区间预测预测效果基本介绍模型特性程序设计参考资料预测效果 基本介绍 Matlab实现QRTCN时间卷积神经网络分位数回归区间预测 QRTCN(Quantile Regres…

Java数据类型常量

目录 一、数据类型 1.1分类 1.2关键字&内存占用&范围 1.3包装类 1.4说明 1.5类型转换 1.6类型提升 二、常量 2.1java中的常量 2.2定义常量 2.3分类 一、数据类型 1.1分类 1.2关键字&内存占用&范围 数据类型关键字内存占用范围字节型byte1字节-128…

【学术会议征稿】2024年信号处理与神经网络应用国际学术会议(SPNNA 2024)

2024年信号处理与神经网络应用国际学术会议&#xff08;SPNNA 2024&#xff09; 2024 International Conference on Signal Processing and Neural Network Applications 2024年信号处理与神经网络应用国际学术会议&#xff08;SPNNA 2024&#xff09;将于2024年12月13日至15…

scratch星际穿越 2024年9月中国电子学会图形化编程 少儿编程 scratch编程等级考试一级真题和答案解析

目录 scratch星际穿越 一、题目要求 1、准备工作 2、功能实现 二、案例分析 1、角色分析 2、背景分析 3、前期准备 三、解题思路 1、思路分析 2、详细过程 四、程序编写 五、考点分析 六、 推荐资料 1、入门基础 2、蓝桥杯比赛 3、考级资料 4、视频课程 5、…

DevExpress WinForms中文教程:Data Grid - 如何完成数据输入验证?

本教程介绍DevExpress WinForm的Data Grid控件是如何利用网格组件完成数据输入验证的。 P.S&#xff1a;DevExpress WinForms拥有180组件和UI库&#xff0c;能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForms能完美构建流畅、美观且易于使用的应用程序…

Python酷库之旅-第三方库Pandas(140)

目录 一、用法精讲 631、pandas.Timestamp类 631-1、语法 631-2、参数 631-3、功能 631-4、返回值 631-5、说明 631-6、用法 631-6-1、数据准备 631-6-2、代码示例 631-6-3、结果输出 632、pandas.Timestamp.asm8属性 632-1、语法 632-2、参数 632-3、功能 632…

java类和对象_成员变量方法修饰符局部变量this关键字-cnblog

java类和对象 成员变量 权限修饰符 变量类型 变量名; 成员变量可以是任意类型,整个类是成员变量的作用范围 成员变量 成员方法 权限修饰符 返回值类型 方法名() 成员方法可以有参数&#xff0c;也可以有返回值&#xff0c;用return声明 权限修饰符 private 只能在本类…

IDEA必装的插件:Spring Boot Helper的使用与功能特点

在IntelliJ IDEA中&#xff0c;Spring Boot Helper插件是一个非常实用的工具&#xff0c;可以帮助我们更快速地创建和管理Spring Boot项目。以下是Spring Boot Helper插件的详细介绍和使用方法&#xff1a; 激活码地址: 点击获取 一、安装Spring Boot Helper插件 1 打开Intell…

如何设计三极管放大电路?

设计放大电路 分压式串联负反馈放大电路 可以看下面这个视频 , 讲得更加详细 366-单管放大电路偏置电阻的计算&#xff0c;看完自己也会设计一个_哔哩哔哩_bilibili 计算流过电阻Rb2的电流过程中,工程当中常发现Rb2上的电流是Ib的5倍 , 因此由基尔霍夫电流定律也能知道流过R…

Java的基础概念和常识(二)

什么是字节码&#xff1f;采用字节码的好处是什么&#xff1f; 字节码&#xff08;Byte-code&#xff09;是一种中间形式的代码&#xff0c;是源代码编译后生成的一种低级表示&#xff0c;通常是在编译阶段生成的。在 Java 中&#xff0c;JVM 可以理解的代码就叫做字节码&…

K8s(学习笔记)

swap分区是什么呀&#xff1f; 什么是ipvs呀&#xff1f; yaml是什么呀&#xff1f;&#xff1f;&#xff1f; p20看不下去了&#xff01;&#xff01;&#xff01;