ArrayList 分析以及相关方法介绍

简介: java.util.ArrayList 是我们最常用的一个类,ArrayList 底层是动态数组,读者可以把它理解为数组的实现

ArrayList简介:

java.util.ArrayList 是我们最常用的一个类,ArrayList 底层是动态数组,读者可以把它理解为数组的实现

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

}

如上代码我们可以看到 ArrayList 继承了 AbstractList() 抽象类,并实现了 List, RandomAccess, Cloneable, Serializable 接口

AbstractList :

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>{}

可以看到AbstractList 继承了 AbstractCollection 接口, 并实现了List 接口

AbstractCollection :

public abstract class AbstractCollection<E> implements Collection<E>{}

AbstractCollection 是一个抽象类,实现了Collection 接口,并提供了某些方法的具体实现。

Collection:

Collection 是一个顶级接口,是很多集合类的顶级接口,继承了Iterable ,支持轻量级遍历其中元素

public interface Collection<E> extends Iterable<E>{}

List :

ArrayList 实现了List接口,List 也是一个和Collection 媲美的顶级接口,继承了Collection 接口

public interface List<E> extends Collection<E>{}

它是许多集合类的父类,

eg:

List list = new ArrayList();

List list2 = new LinkedList();

RandomAccess

RandomAccess 也是一个顶级接口,实现了此接口的类支持随机访问

Cloneable

Cloneable 接口是一个顶级接口,实现了此接口的类支持浅拷贝

Serializable

实现此接口的类支持序列化的功能

ArrayList 相关方法介绍

0.jpg

1.jpg

trimToSize()

2.jpg


代码表示

实践才是检验真理最好的方式:

importjava.util.*;

/**
* 详述ArrayList 基本用法
*/
public class ArrayListTest{

private static class SortList implements Comparator<String>{

@Override
public int compare(String o1, String o2) {
Integeri1=Integer.valueOf(o1);
Integeri2=Integer.valueOf(o2);
if(i1<i2){
return-1;
}elseif(i1==i2){
return0;
}
return1;
}
}

// 使用可变参数,能够接受任意个参数
public Set<String> putSet(String...args){
Set<String> sets = new HashSet<>();
for(String str: args){
sets.add(str);
}
return sets;
}

public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("111");
list.add("222");

// 在指定位置添加元素
list.add(0,"333");
System.out.println(list);

// 进行外部排序
list.sort(newSortList());
System.out.println(list);

list.clear();
System.out.println(list.size());

// 使用addAll添加元素
ArrayList Testat = newArrayListTest();
list.addAll(at.putSet("1","2","3"));

Iterator<String> it = list.iterator();
while(it.hasNext()){
System.out.println(it.next());
// 移除所有元素
it.remove();
}

System.out.println("list是否为空 ? "+list.isEmpty());

list.add("111");
// 在指定位置添加一个set集合
list.addAll(0,at.putSet("1","2","3"));
System.out.println(list);

// 是否包含指定元素
if(list.contains("111")) {
list.remove("111");
}
System.out.println(list);

System.out.println(list.indexOf("1"));
// 注意subList()这个方法是左开右闭区间,Java 中很多都是类似的
System.out.println(list.subList(0,3));

// 扩大list的容量
list.ensureCapacity(10);
// 去掉list空闲的容量
list.trimToSize();

// 获取某个特定的元素
System.out.println(list.get(1));

// 创建一个list的双向链表
ListIterator<String> listIterator = list.listIterator();
while(listIterator.hasNext()){
// 移到list的末端
System.out.println(listIterator.next());
}
System.out.println("--------------------------");
while(listIterator.hasPrevious()){
// 移到list的首端
System.out.println(listIterator.previous());
}

// 把list转换为数组
Object[] objects = list.toArray();
System.out.println("objects = "+objects);

}
}


相关方法源码分析

分析源码还是要有代码的实例,跟进去理解每一行的意思,俗话说,有debug,不求人!

add()方法

/**
* Appends the specified element to the end of this list.
* 添加指定的元素在list的末尾
* @param e element to be appended to this list
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/

// 假设第一次添加的是 "111"
public boolean add(E e) {
// size是0,所以size + 1 传的是1
ensureCapacityInternal(size+1); // Increments modCount!!
// elementData[0] = 111 , size++ = 1
elementData[size++] =e;
returntrue;
}

// 此方法用来进行list 扩容
private void ensureCapacityInternal(int minCapacity) {
// 此时elementData 并没有存储元素,为0
if(elementData==DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
// 则minCapacity 取默认初始容量和minCapacity 的最大值 (取1 和 10的最大值)
minCapacity=Math.max(DEFAULT_CAPACITY, minCapacity);
}
// 确保清晰的容量(最小容量与List元素的比较)
ensureExplicitCapacity(minCapacity);
}

// 在list中添加了一个元素,所以会导致结构化的修改,"结构化的修改"见下面解释
// 此时minCapacity 为 10
private void ensureExplicitCapacity(int minCapacity) {
// 次数 + 1
// 这个列表被修改结构的次数(比如添加和删除元素)会用modCount表示. 结构化修改是指的是能够
// 改变列表容量的操作,或者其他方式改变它,导致遍历的过程会产生错误的结果。
modCount++;

// overflow-conscious code
// 10 - 0 > 0 走grow 方法
if(minCapacity-elementData.length>0)
grow(minCapacity);
}

/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
* 增加容量确保容纳足够的元素
*
* @param minCapacity the desired minimum capacity
* 参数传过来的是10
*/
private void grow(int minCapacity) {
// overflow-conscious code
// oldCapacity = 0
intoldCapacity=elementData.length;
// newCapacity = 0
intnewCapacity=oldCapacity+(oldCapacity>>1);
// newCapacity - minCapacity = -10
if(newCapacity-minCapacity<0)
// newCapacity = 10
newCapacity=minCapacity;

// MAX_ARRAY_SIZE = 数组分配的最大空间 = 2147483639
// 一般情况下不会比 MAX_ARRAY_SIZE 还要大
if(newCapacity-MAX_ARRAY_SIZE>0)
newCapacity=hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
// 底层还是用的System.arraycopy(), 关于System.arrayCopy() 读者可以参考我的另一篇博客
elementData=Arrays.copyOf(elementData, newCapacity);
}

输出:

[333, 111, 222]

[111, 222, 333]

0

1

2

3

list是否为空 ? true

[1, 2, 3, 111]

[1, 2, 3]

0

[1, 2, 3]

2

1

2

3

--------------------------

3

2

1

objects = [Ljava.lang.Object;@6e8cf4c6

相关常用的基本数据类型包装类的值: Java基本数据类型包装类常用的值

add(int index, E element)


/**
* Inserts the specified element at the specified position in this
* list. Shifts the element currently at that position (if any) and
* any subsequent elements to the right (adds one to their indices).
* 在list中指定位置插入指定的元素,如果当前位置有元素,就移动当前位置的元素
* 要插入的位置的后面所有元素的位置向前 + 1
*
* @param index index at which the specified element is to be inserted
* @param element element to be inserted
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public void add(int index, E element) {
// 检查 0 这个位置是否越界
rangeCheckForAdd(index);

// 不再赘述,读者可以自行debug
ensureCapacityInternal(size+1); // Increments modCount!!
// 因为从当前位置插入元素,所以当前位置及后面的元素都会向后移动
// 使用System.arraycopy 进行数组复制
System.arraycopy(elementData, index, elementData, index+1,
size-index);
// 为当前元素赋值
elementData[index] =element;
size++;
}

/**
* A version of rangeCheck used by add and addAll.
* 为add 和 addall 提供的范围检查, 不符合条件,抛出IndexOutOfBoundsException 异常
*
*/
private void rangeCheckForAdd(intindex) {
if(index>size||index<0)
thrownewIndexOutOfBoundsException(outOfBoundsMsg(index));
}

            </div>
目录
相关文章
|
Java 数据管理 关系型数据库
机票预订系统(java+mysql+navicat)
机票预订系统(java+mysql+navicat)
机票预订系统(java+mysql+navicat)
|
11月前
|
存储 安全 iOS开发
内存卡怎么格式化?6个格式化方法供你选
随着使用时间的增加,内存卡可能会因为数据积累、兼容性或是文件系统损坏等原因需要进行格式化。那么怎样正确格式化内存卡呢?格式化内存卡的时候需要注意什么呢?本文会给大家提供详细的步骤,帮助大家轻松完成格式化内存卡的操作。
|
7月前
|
开发框架 前端开发 搜索推荐
《数字藏品社交化破局:React Native与Flutter的创新实践指南》
NFT(非同质化代币)为数字资产赋予了独一无二的身份标识,React Native和Flutter两大跨平台开发框架则为NFT数字藏品的展示与交易提供了技术支持。React Native通过组件化开发模式,结合丰富的第三方库,实现高清图片、动态视频及3D模型的精美展示,并支持多种支付方式,确保流畅的交易体验。Flutter凭借高性能渲染和自绘制UI特性,带来沉浸式动画效果和快速响应的交易操作,兼容多平台以优化用户体验。此外,应用可通过VR/AR技术提供多样化展示形式,利用智能合约保障交易安全,同时融合社交互动功能,让用户分享、拍卖数字藏品,增强社区参与感。
158 19
|
传感器 物联网 数据挖掘
新技术趋势与应用:物联网与虚拟现实的未来发展###
随着科技的迅猛发展,物联网(IoT)和虚拟现实(VR)已成为引领未来的重要技术趋势。本文旨在探讨这两项新兴技术的发展趋势和应用场景,通过分析当前技术现状、挑战及未来前景,揭示物联网和虚拟现实在各领域的潜在影响和应用价值。研究表明,物联网在智能家居、智慧城市、工业自动化等方面具有广泛的应用前景;而虚拟现实则在游戏娱乐、教育培训、医疗健康等领域展现出巨大的潜力。本文认为,随着技术的不断进步,物联网和虚拟现实将深度融合,为社会经济发展带来新的机遇和挑战。 ###
534 59
|
机器学习/深度学习 API 数据库
淘宝拍立淘按图搜索商品API接口详解
拍立淘按图搜索商品API接口提供了一种通过上传商品图片来搜索相似或相同商品的功能。用户只需上传一张商品图片,系统通过图像识别技术对该图片进行分析和处理,提取出商品的特征信息,并在商品数据库中进行匹配搜索,最终返回与上传图片相似或相同的商品列表。这一功能广泛应用于电商平台、购物应用以及图像搜索等领域,极大地提升了用户的购物体验。
|
存储 消息中间件 缓存
中间件redis的使用
【9月更文挑战第28天】Redis 是一个开源的、基于内存的数据结构存储系统,可用作数据库、缓存和消息中间件。它支持多种数据结构,如字符串、哈希、列表、集合和有序集合等,使其在各种应用场景中表现出色。Redis 作为缓存中间件能显著提高数据访问速度,其缓存过期策略有助于管理数据生命周期。在 .NET 应用程序中使用 Redis 缓存,可通过安装 `StackExchange.Redis` 库并连接到 Redis 服务器来实现数据的读写操作。此外,Redis 作为消息中间件,基于生产者-消费者模型实现消息队列,确保消息的可靠性和顺序性。
503 4
|
存储 安全 C++
C++ 11新特性之unique_ptr
C++ 11新特性之unique_ptr
427 4
|
Linux C语言
C语言 多进程编程(三)信号处理方式和自定义处理函数
本文详细介绍了Linux系统中进程间通信的关键机制——信号。首先解释了信号作为一种异步通知机制的特点及其主要来源,接着列举了常见的信号类型及其定义。文章进一步探讨了信号的处理流程和Linux中处理信号的方式,包括忽略信号、捕捉信号以及执行默认操作。此外,通过具体示例演示了如何创建子进程并通过信号进行控制。最后,讲解了如何通过`signal`函数自定义信号处理函数,并提供了完整的示例代码,展示了父子进程之间通过信号进行通信的过程。
|
人工智能 自动驾驶 安全
AI与未来生活:技术如何重塑我们的世界
在这篇文章中,我们将深入探讨人工智能(AI)如何改变我们的生活方式。从智能家居到自动驾驶汽车,从虚拟助手到医疗诊断,AI正在逐步渗透到我们生活的方方面面。我们将看到AI如何提高我们的生活效率,改善我们的生活质量,甚至帮助我们解决一些看似无法解决的问题。然而,我们也将讨论AI带来的挑战和道德问题,以及我们需要如何应对这些问题。最后,我们将展望AI在未来可能的发展趋势,以及它可能带来的更深远的影响。
|
算法 大数据 量子技术
探索未来:量子计算在解决复杂问题中的潜力与挑战
本文深入探讨了量子计算技术如何为解决传统计算机无法有效处理的复杂问题开辟新路径。通过分析量子计算的原理、当前发展状况以及面临的主要技术挑战,文章揭示了量子计算在未来可能带来的革命性变化,并讨论了其对科学研究、密码学和大数据处理等领域的潜在影响。