Java集合源码学习(2)ArrayList

news2024/11/15 17:30:11

1 概述

ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存。

ArrayList不是线程安全的,只能用在单线程环境下,多线程环境下可以考虑用Collections.synchronizedList(List l)函数返回一个线程安全的ArrayList类,也可以使用concurrent并发包下的CopyOnWriteArrayList类。

ArrayList实现了Serializable接口,因此它支持序列化,能够通过序列化传输,实现了RandomAccess接口,支持快速随机访问,实际上就是通过下标序号进行快速访问,实现了Cloneable接口,能被克隆。

每个ArrayList实例都有一个容量,该容量是指用来存储列表元素的数组的大小。它总是至少等于列表的大小。随着向ArrayList中不断添加元素,其容量也自动增长。自动增长会带来数据向新数组的重新拷贝,因此,如果可预知数据量的多少,可在构造ArrayList时指定其容量。在添加大量元素前,应用程序也可以使用ensureCapacity操作来增加ArrayList实例的容量,这可以减少递增式再分配的数量。

注意,此实现不是同步的。如果多个线程同时访问一个ArrayList实例,而其中至少一个线程从结构上修改了列表,那么它必须保持外部同步。

ArrayList继承AbstractList,实现了List、 RandomAccess、Cloneable、Serializable接口, 为ArrayList内部是用一个数组存储元素值,相当于一个大小可变的数组,也就是动态数组。 由于ArrayList底层是数组实现的,所以可以随机访问。

public class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable 

(1)继承和实现继承了AbstractList,实现了List:ArrayList是一个数组队列,提供了相关的添加、删除、修改、遍历等功能。实现RandmoAccess接口:即提供了随机访问功能。RandmoAccess是java中用来被List实现,为List提供快速访问功能的在ArrayList中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。实现了Cloneable接口:即覆盖了函数clone(),能被克隆。实现java.io.Serializable接口:这意味着ArrayList支持序列化,能通过序列化去传输。

(2)线程安全ArrayList不是线程安全的。建议在单线程中才使用ArrayList,而在多线程中可以选择Vector或者CopyOnWriteArrayList。同样,HashMap也是线程不安全的,如果需要并发访问应该使用Hashtable(遗留类)或ConcurrentHashMap。

private static final int DEFAULT_CAPACITY = 10;//默认容量是10 

私有属性:

/** * The array buffer into which the elements of the ArrayList are stored. * The capacity of the ArrayList is the length of this array buffer. */ private transient Object[] elementData; /** * The size of the ArrayList (the number of elements it contains). * * @serial */ private int size; 

elementData存储ArrayList内的元素,size表示它包含的元素的数量。

有个关键字需要解释:transient。

Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。

经常在实现了 Serializable接口的类中能看见transient关键字。这个关键字并不常见。 transient关键字的作用是:阻止实例中那些用此关键字声明的变量持久化;当对象被反序列化时(从源文件读取字节序列进行重构),这样的实例变量值不会被持久化和恢复。当某些变量不想被序列化,同是又不适合使用static关键字声明,那么此时就需要用transient关键字来声明该变量。

除了以上两个成员变量,我们还需要掌握一个变量,它是

protected transient int modCount = 0; 

这个变量主要作用是防止在进行一些操作时,改变了ArrayList的大小,那将使得结果不可预测。

构造函数:

/**无参构造:
 * Constructs an empty list with an initial capacity of ten.
 */
public ArrayList() {this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

/**有参构造
 * Constructs an empty list with the specified initial capacity.
 *
 * @paraminitialCapacitythe initial capacity of the list
 * @throws IllegalArgumentException if the specified initial capacity
 * is negative
 */
public ArrayList(int initialCapacity) {if (initialCapacity > 0) {this.elementData = new Object[initialCapacity];} else if (initialCapacity == 0) {this.elementData = EMPTY_ELEMENTDATA;} else {throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);}
}

/**参数为集合的有参构造
 * Constructs a list containing the elements of the specified
 * collection, in the order they are returned by the collection's
 * iterator.
 *
 * @param c the collection whose elements are to be placed into this list
 * @throws NullPointerException if the specified collection is null
 */
public ArrayList(Collection<? extends E> c) {elementData = c.toArray();if ((size = elementData.length) != 0) {// c.toArray might (incorrectly) not return Object[] (see 6260652)if (elementData.getClass() != Object[].class)elementData = Arrays.copyOf(elementData, size, Object[].class);} else {// replace with empty array.this.elementData = EMPTY_ELEMENTDATA;}
} 

常用的方法

boolean add(E e) 
将指定的元素添加到此列表的尾部。

void add(int index, E element) 
将指定的元素插入此列表中的指定位置

boolean addAll(Collection<? extends E> c) 
按照指定 collection 的迭代器所返回的元素顺序,将该 collection 中的所有元素添加到此列表的尾部。 

boolean addAll(int index, Collection<? extends E> c) 
从指定的位置开始,将指定 collection 中的所有元素插入到此列表中。 

void clear() 
移除此列表中的所有元素。 

Object clone() 
返回此 ArrayList 实例的浅表副本。 

boolean contains(Object o) 
如果此列表中包含指定的元素,则返回 true。 

void ensureCapacity(int minCapacity) 
如有必要,增加此 ArrayList 实例的容量,以确保它至少能够容纳最小容量参数所指定的元素数。 

E get(int index) 
返回此列表中指定位置上的元素。 

int indexOf(Object o) 
返回此列表中首次出现的指定元素的索引,或如果此列表不包含元素,则返回 -1。 

boolean isEmpty() 
如果此列表中没有元素,则返回 true 

int lastIndexOf(Object o) 
返回此列表中最后一次出现的指定元素的索引,或如果此列表不包含索引,则返回 -1。 

E remove(int index) 
移除此列表中指定位置上的元素。 

boolean remove(Object o) 
移除此列表中首次出现的指定元素(如果存在)。 

protected void removeRange(int fromIndex, int toIndex) 
移除列表中索引在 fromIndex(包括)和 toIndex(不包括)之间的所有元素。 

E set(int index, E element) 
用指定的元素替代此列表中指定位置上的元素。 

int size() 
返回此列表中的元素数。 

Object[] toArray() 
按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组。

void trimToSize() 
将此 ArrayList 实例的容量调整为列表的当前大小。应用程序可以使用此操作来最小化 ArrayList 实例的存储量。 

遍历方式:ArrayList支持3种遍历方式1.通过迭代器遍历。即通过Iterator去遍历2.随机访问,通过索引值去遍历,ArrayList实现了RandomAccess接口,它支持通过索引值去随机访问元素3.for循环遍历

遍历ArrayList时,使用随机访问(即通过索引序号访问)效率最高,而使用迭代器的效率相对较低。

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

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

相关文章

Commonsense and Named Entity Aware Knowledge Grounded Dialogue Generation

摘要 motivation&#xff1a; 以外部知识为基础&#xff0c;在对话历史背景下解释语言模式&#xff0c;如省写、回指和共同引用&#xff0c;对对话的理解和生成至关重要。 this paper&#xff1a; 在本文中&#xff0c;我们提出了一种新的开放域对话生成模型&#xff0c;该模型…

【C++】vector的使用及其迭代器失效问题

文章目录一、vector介绍二、vector使用1. 常用构造函数2. 迭代器3. 空间操作4. 增删查改5. 动态二维数组三、vector迭代器失效问题1. 扩容导致迭代器失效2. erase导致迭代器失效3. g对迭代器失效的处理一、vector介绍 vector是表示可变大小数组的序列容器。与数组一样&#xf…

vue打包exe

文章目录一、前言二、实现方法1.跑通示例代码 electron-quick-start<1>clone示例代码<2>进入项目根目录&#xff0c;下载依赖<3>测试运行2.打包自己的 vue 项目3.将vue项目整合到示例代码中打包exe<1>将打包好的 dist 文件夹复制到示例代码 electron-q…

【Linux】gdb调试器的使用

All is well that ends well.结果好就是好。 个人主页&#xff1a;阿润菜菜 简介 GDB是GNU开源组织发布的一个强大的Linux下的程序调试工具。 Windows 操作系统中&#xff0c;我们更习惯使用一些已经集成好的开发环境&#xff08;IDE&#xff09;&#xff0c;如 VS、VC、Dev-…

LeetCode461. 汉明距离,x与y异或,之后用f(x)=x (x−1))次数与Integer.bitCount求二进制1的个数

两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。 给你两个整数 x 和 y&#xff0c;计算并返回它们之间的汉明距离。 1.x ^ y异或&#xff0c;用f(x)x & (x−1)&#xff09;次数求二进制中1的个数&#xff0c;那么 f(x) 恰为x删去其二进制表示中…

C语言_文件操作(上)

目录 1. 什么是文件 2. 文件名 3. 文件类型 4. 文件缓冲区 5. 文件指针 6. 文件的打开和关闭_fopen_fclose 7. 文件的顺序读写 7.1 fputc 7.2 fgetc 7.3 fputs 7.4 fgets 7.5 fscanf 7.6 fprintf 7.7 fread 7.8 fwrite 7.9 对比scanf/printf、fscanf/fprintf、…

java实现dwg转pdf

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、无奈选择第二种二、jar引入1.jar地址2.使用jar,完成dwg转为pdf总结前言 由于公司需要最近研究一个cad文件需要在浏览器中展示,经过研究发现大致有两种方式:…

JVM-围观如何打破双亲委派机制

下面手把手用代码来实现打破JVM的双亲委派机制一、Tomcat打破双亲委派机制以Tomcat类加载为例&#xff0c;Tomcat作为web容器&#xff0c; 那么它要解决什么问题呢&#xff1f;Tomcat 如果使用默认的双亲委派类加载机制行不行&#xff1f;1.1 Tomcat作为web容器&#xff0c; 那…

科技云报道:CES 2023:自动驾驶、元宇宙备受瞩目

科技云报道原创。 在被疫情扰乱了两年之后&#xff0c;2023年CES终于回归正常了。 1月5日-8日&#xff0c;CES 2023在拉斯维加斯举行。作为当前全球规模最大、影响力最广泛的消费类电子技术年展&#xff0c;本届展会涵盖的重要主题包括可持续性、数字健康、Web3与元宇宙以及人…

教你如何快速使用店铺管理系统

一、客户管理1、客户资料客户资料报表展示所有新客的数据信息&#xff0c;在此报表可进行会员开卡及新增客户操作&#xff1b;提交会员开卡表单之后&#xff0c;由数据助手更新该客户的会员卡信息至客户信息表单&#xff1b;点击新增客户弹出客户信息表单&#xff0c;默认客户分…

python自学之《21天学通Python》(8)

第11章 文件与文件系统 编写程序来解决实际项目时&#xff0c;很多时候都离不开文件和文件系统的操作。程序本身就是保存在文件系统的文件中的。文件既可以保存程序代码&#xff0c;也可以用来保存各种输入与输出数据。文件和文件系统的处理是任何高级程序设计语言必不可少的一…

Node.js教程笔记(一)

学习目标 1、初识Nodejs 2、fs文件系统模块 3、path路径模块 4、http模块 一、初识Node.js 1.1 浏览器中的JavaScript的运行环境 1、浏览器中的JavaScript的组成部分 2、为什么JavaScript可以在浏览器中被执行&#xff1f; 3、为什么JavaScript可以操作Dom和Bom&#xff…

智公网:公务员的专业限制有哪些?

公务员报考的要求越来越高了&#xff0c;尤其是限制专业这一块&#xff0c;直接阻断了很多人想要跨专业的想法。但是没有办法专业这个条件是硬性的&#xff0c;所以在报考之前一定要看清报考要求。 公务员性质也是比较特殊的&#xff0c;像是一些比较热门专业&#xff0c;在公…

线程安全☞原子性

何为原子性? 原子性&#xff1a;一条线程在执行一系列程序指令操作时&#xff0c;该线程不可中断。一旦出现中断&#xff0c;那么就可能会导致程序执行前后的结果不一致。与数据库中的原子性&#xff08;事务管理体现&#xff09;是相同的 概括&#xff1a;一段程序只能由一条…

Go语言设计与实现 -- 浅谈垃圾回收机制

概述 GC就是垃圾回收机制。而我们知道&#xff0c;内存区域是分成几个块儿的&#xff0c;例如&#xff1a; 堆区&#xff1a;为对象分配内存空间&#xff0c;在栈区和bss区之间存放函数参数&#xff0c;返回值&#xff0c;局部变量全局区&#xff1a;常量区&#xff08;const…

第一批“阳康”涌向三亚,最大的赢家或是携程

在2022年接近尾声时&#xff0c;给居民出行带来近三年困扰的疫情防控&#xff0c;终于迎来了好消息。随着国家“新十条”防控新政策的出台以及优化&#xff0c;过去出门不便、频繁查验核酸码的时代一去不返。尤其是各地逐步放宽出入境管控政策后&#xff0c;在线旅游行业也迎来…

PMP的价值有哪些?

我个人认为&#xff0c;考证只有两个出发点是正确的。一是为了提升自己或者满足自己的兴趣&#xff0c;另一个是和自己的职业规划相关。 比如&#xff0c;有同学想提升自己英语能力&#xff0c;可以考四六级&#xff0c;或者更厉害一点的考雅思、托福。比如&#xff0c;有的同…

电脑自动关机是什么原因?4个解决方法,赶紧码住收藏!

正在使用电脑&#xff0c;突然自动关机。如果没有及时保存好资料&#xff0c;我们辛辛苦苦写的资料就会付诸东流。电脑自动关机是什么原因&#xff1f;其实主要是以下这4个方面的原因。你可以根据下面不同的原因来对症下药&#xff0c;寻找解决电脑自动关机的最好方法&#xff…

直播弹幕系统(七)- 利用动态创建队列完成直播间独立聊天

直播弹幕系统&#xff08;七&#xff09;- 利用动态创建队列完成直播间独立聊天前言一. 动态创建队列1.1 测试 - 动态创建队列1.2 测试 - 聊天室独立前言 上一篇 SpringBoot STOMP RabbitMQ&#xff08;使用MQ替代Spring代理&#xff09; 中主要讲解了如何整合STOMP以及Rabb…

Vue条件语句中v-if、v-else、v-else-if的用法

文章目录1、v-if和v-else结合使用1.1 出现的错误2、v-if、v-else-if和v-else的联合使用2.1 出现的错误3、如果想要同时切换多个元素3.1 效果展示1、v-if和v-else结合使用 v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面&#xff0c;否则它将不会被识别。 <span…