百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT知识 > 正文

java ArrayList类详解及Vector类简介

liuian 2025-01-14 15:20 86 浏览

/**

* ArrayList详解及Vector简介

*/

public class TestArrayList2 {

public static void main(String[] args) {

/* ArrayList源码

public class ArrayList<E> extends AbstractList<E>

implements List<E>, RandomAccess, Cloneable, java.io.Serializable

//泛型类<E> 实现List<E>

private static final int DEFAULT_CAPACITY = 10;

//默认容量10 当第一次添加元素时如果一次性添加数量小于等于10会将容器的容量capacity变为10

private static final Object[] EMPTY_ELEMENTDATA = {};

//空_元素数据

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

//默认容量_空_元素数据 空数组 new ArrayList()无参时会将容器的数组设定为{}

transient Object[] elementData;

//elementData元素数据 Object[]数组 用于存放容器中的元素

private int size;

//.size()返回的size 容器中元素的数量

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);

}

}

//有参构造器 initial最初的 设定容器初始大小size为initialCapacity

//当参数==0时将elementData赋值为EMPTY_ELEMENTDATA

public ArrayList() {

this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;

}

//无参构造器 将elementData赋值为DEFAULTCAPACITY_EMPTY_ELEMENTDATA

public ArrayList(Collection<? extends E> c) {

Object[] a = c.toArray();

if ((size = a.length) != 0) {

if (c.getClass() == ArrayList.class) {

elementData = a;

} else {

elementData = Arrays.copyOf(a, size, Object[].class);

}

} else {

elementData = EMPTY_ELEMENTDATA;

}

}

//将容器c传参给构造器 将this.size设为容器c的元素数 将this.elementData设为容器c的数组 如果c不是ArrayList类将数组转换为Object[]再赋值给elementData

public void trimToSize() {

modCount++;

if (size < elementData.length) {

elementData = (size == 0)

? EMPTY_ELEMENTDATA

: Arrays.copyOf(elementData, size);

}

}

//trim修剪 将elementData中的元素拷贝至新的数组[size] 修剪掉数组中null未使用的索引 将数组的长度改为存放的元素总数size

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

//size最大值为int最大值-8

public int size() {

return size;

}

//.size()方法返回size值

public boolean isEmpty() {

return size == 0;

}

//当size为0时判断容器为空

public int indexOf(Object o) {

if (o == null) {

for (int i = 0; i < size; i++)

if (elementData[i]==null)

return i;

} else {

for (int i = 0; i < size; i++)

if (o.equals(elementData[i]))

return i;

}

return -1;

}

//从前往后遍历elementData 查找第一个和参数o相同的元素 如果参数是null则返回elementData中第一个null 不存在返回-1

public boolean contains(Object o) {

return indexOf(o) >= 0;

}

//indexOf()不返回-1即容器中存在和参数o相同的元素

public int lastIndexOf(Object o) {

if (o == null) {

for (int i = size-1; i >= 0; i--)

if (elementData[i]==null)

return i;

} else {

for (int i = size-1; i >= 0; i--)

if (o.equals(elementData[i]))

return i;

}

return -1;

}

//for循环从末位size-1往前查找

public Object[] toArray() {

return Arrays.copyOf(elementData, size);

}

//elementData是容器的存放元素的数组 size是元素真实的总数 数组中元素是从index0往后顺序存入的 当数组没有存满时数组中后面的位为空

//Arrays.copyOf()创建一个新的数组 大小为size容器的元素真实总数 将elementData从[0]-[size-1]即所有元素拷贝到新数组中返回 返回类型为Object[]不是泛型

public <T> T[] toArray(T[] a) {

if (a.length < size)

return (T[]) Arrays.copyOf(elementData, size, a.getClass());

System.arraycopy(elementData, 0, a, 0, size);

if (a.length > size)

a[size] = null;

return a;

}

//将容器中的元素拷贝到和形参a一致的数组类型的数组中返回 如果a的长度小于size则返回一个新的数组T[size] 否则将元素拷贝到a中 从index0位开始 比size长时将[size]位设为null 返回a

public E get(int index) {

rangeCheck(index);

return elementData(index);

}

//返回索引位的元素 先判断index在不在size范围内

E elementData(int index) {return (E) elementData[index];}

public E set(int index, E element) {

rangeCheck(index);

E oldValue = elementData(index);

elementData[index] = element;

return oldValue;

}

//替换元素 返回被替换元素

public boolean add(E e) {

ensureCapacityInternal(size + 1);

elementData[size++] = e;

return true;

}

//添加元素 先确保ensure 容量 如果elementData数组的长度不足会进行扩容

//将e赋值给[size]位 size++ size反映容器中元素的数量 每次增减元素size都会改变相应的数量

//add(E e)是增加一个元素的方法 所以将size+1传参进ensureCapacityInternal()方法中判断是否需要扩容

private void ensureCapacityInternal(int minCapacity) {

ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));

}

//minCapacity为需要的容器空间 calculateCapacity(elementData, minCapacity)方法如下

private static int calculateCapacity(Object[] elementData, int minCapacity) {

if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {

return Math.max(DEFAULT_CAPACITY, minCapacity);

}

return minCapacity;

}

//calculate计算 如果容器由无参构造器生成,在初始化后没有添加元素即elementData依然等于默认容量空{},将默认容量10和需要的容器空间比较选最大值返回 即初次添加元素后容器的size最小为10

//如果容器内已存在元素则返回所需空间的值 返回值作为参数传给ensureExplicitCapacity()方法如下

private void ensureExplicitCapacity(int minCapacity) {

modCount++;

if (minCapacity - elementData.length > 0)

grow(minCapacity);

}

//explicit明确的 modCount修改计数 如果所需空间比当前elementData的长度大则需要扩容grow 方法如下

private void grow(int minCapacity) {

int oldCapacity = elementData.length;

int newCapacity = oldCapacity + (oldCapacity >> 1);

if (newCapacity - minCapacity < 0)

newCapacity = minCapacity;

if (newCapacity - MAX_ARRAY_SIZE > 0)

newCapacity = hugeCapacity(minCapacity);

elementData = Arrays.copyOf(elementData, newCapacity);

}

//先预设将数组的长度变为1.5倍 如果满足所需空间则扩容1.5 如果不满足则将空间扩容至所需空间的大小 扩容会生成新的数组并将原数组拷贝过来

public void add(int index, E element) {

rangeCheckForAdd(index);

ensureCapacityInternal(size + 1);

System.arraycopy(elementData, index, elementData, index + 1,

size - index);

elementData[index] = element;

size++;

}

//和add(E)基本相同 将从index位开始的元素拷贝到index+1位开始的位置 长度size-index即后移元素的总数 拷贝后将新元素赋值给index位

public E remove(int index) {

rangeCheck(index);

modCount++;

E oldValue = elementData(index);

int numMoved = size - index - 1;

if (numMoved > 0)

System.arraycopy(elementData, index+1, elementData, index,

numMoved);

elementData[--size] = null; // clear to let GC do its work

return oldValue;

}

//将被删除的元素返回 判断index位后面还有元素则将后面元素从index+1位开始拷贝至index位开始 将--size即原最后一个元素位赋null size减小

public boolean remove(Object o) {

if (o == null) {

for (int index = 0; index < size; index++)

if (elementData[index] == null) {

fastRemove(index);

return true;

}

} else {

for (int index = 0; index < size; index++)

if (o.equals(elementData[index])) {

fastRemove(index);

return true;

}

}

return false;

}

//for遍历数组直到size位之前 当匹配到第一个相同元素时删除并返回true 所以只能删除第一个 fastRemove()方法不返回boolean

public void clear() {

modCount++;

for (int i = 0; i < size; i++)

elementData[i] = null;

size = 0;

}

//遍历数组全设为null size设为0

public boolean addAll(Collection<? extends E> c) {

Object[] a = c.toArray();

int numNew = a.length;

ensureCapacityInternal(size + numNew); // Increments modCount

System.arraycopy(a, 0, elementData, size, numNew);

size += numNew;

return numNew != 0;

}

//和add()类似 如果所需空间大于数组的长度会扩容 拷贝原数组内容至新的数组中 再将形参c的数组拷贝到size位开始的位置即this容器的末尾

//返回值是判断形参c容器是否为空

public boolean addAll(int index, Collection<? extends E> c) {

rangeCheckForAdd(index);

Object[] a = c.toArray();

int numNew = a.length;

ensureCapacityInternal(size + numNew);

int numMoved = size - index;

if (numMoved > 0)

System.arraycopy(elementData, index, elementData, index + numNew,

numMoved);

System.arraycopy(a, 0, elementData, index, numNew);

size += numNew;

return numNew != 0;

}

//多了一个步骤判断index位及后面是否有元素 将index位及后面的元素拷贝到index+numNew开始的位置

public boolean removeAll(Collection<?> c) {

Objects.requireNonNull(c);

return batchRemove(c, false);

}

//removeAll和retainAll都通过batchRemove()执行

public boolean retainAll(Collection<?> c) {

Objects.requireNonNull(c);

return batchRemove(c, true);

}

//Objects.requireNonNull()判断c为null则抛异常 否则返回c batchRemove()方法如下

private boolean batchRemove(Collection<?> c, boolean complement) {

final Object[] elementData = this.elementData;

int r = 0, w = 0;

//r读 w写

boolean modified = false;

try {

for (; r < size; r++)

if (c.contains(elementData[r]) == complement)

//遍历判断this中的元素是否存在于c中 complement补充/交集

//如果取交集retainAll时complement为true 需要contains()为true 即当前元素在c中存在(true)==取交集(true) 执行拷贝

elementData[w++] = elementData[r];

//如果取差集removeAll complement为false 需要contains()为false即当前元素在c中不存在 false==false 才执行拷贝

} finally {

if (r != size) {

System.arraycopy(elementData, r,

elementData, w,

size - r);

w += size - r;

//如果执行过程中出现异常导致没有完成数组的遍历 会将剩余的部分拷贝至已完成部分的末尾来结束方法

}

if (w != size) {

// clear to let GC do its work 当索引位赋null 原元素/对象不再被调用后会被垃圾回收GC

for (int i = w; i < size; i++)

elementData[i] = null;

modCount += size - w;

size = w;

modified = true;

//w即符合要求的元素数 将符合的元素顺序放在数组的前面 将后面的位置全部赋null 完成交集或者差集

}

}

return modified;

}

*/

}

}

/*

Vector为List接口的实现类 基础用法和ArrayList相同 vector矢量

ArrayList线程不安全 效率高

Vector线程安全 效率低

类似StringBuilder和StringBuffer的区别

List<String> v = new Vector<>();同样通过List接口引用

Vector<>()源码:

protected Object[] elementData;同样使用elementData数组存储元素

protected int elementCount;用于表示元素总数 作用同size

public Vector() {this(10);}无参构造器直接初始size为10

private void grow(int minCapacity) {

// 扩容

int oldCapacity = elementData.length;

int newCapacity = oldCapacity + ((capacityIncrement > 0) ?

capacityIncrement : oldCapacity);

//Vector容器的空间是2倍扩容

if (newCapacity - minCapacity < 0)

newCapacity = minCapacity;

if (newCapacity - MAX_ARRAY_SIZE > 0)

newCapacity = hugeCapacity(minCapacity);

elementData = Arrays.copyOf(elementData, newCapacity);

}

*/

相关推荐

gho文件安装win10系统方法(gho文件怎么重装系统)

不建议这么操作,如果真的要复制,也是很麻烦的,首先要删除win10里面所有的驱动,注意是所有的,然后关机,注意不能重启进入系统,否则又要重新再来,其次找个U盘pe启动盘或者启动光盘,在开机进入pe系统...

下载163免费邮箱(免费下载网易邮箱163)

第一步:首先,我们手机里要有一个浏览器,小编比较用UC浏览器,当然可以用手机都是自带网页浏览器的,我这边的手机下载网易邮箱第二步:打开UC浏览器或者带浏览器,我们在地址栏上直接输入最新网易邮箱下载安装...

windows microsoft(windows microsoft store加载不出)

电脑开机时出现MicrosoftWindows遇到意外错误,可以尝试用最后一次正确配置来恢复一下。1、重启电脑。2、在电脑显示完硬件信息之后,进入windows界面之前,按F8键。3、在出现的选项菜单...

不读u盘的解决办法(不读u盘怎么回事)

u盘在电脑里读不出来,出现这种情况,可以用以下方法解决:1、判断U盘是否已经正确插入USB接口,你可以拔下来换个插口试试。2、如果已经启用了USB设备但运行不正常,解决办法为在设备管理器中删除“通用...

win11怎么激活(win11怎么激活office)

目前,Windows11的永久激活方法还没有被公开或者确认。不过,你可以尝试以下几种方法来激活Windows11:使用数字许可证:如果你的电脑已经安装了Windows10并且已经激活,那么你可以...

笔记本电脑快捷键大全(笔记本电脑快捷键大全常用)
  • 笔记本电脑快捷键大全(笔记本电脑快捷键大全常用)
  • 笔记本电脑快捷键大全(笔记本电脑快捷键大全常用)
  • 笔记本电脑快捷键大全(笔记本电脑快捷键大全常用)
  • 笔记本电脑快捷键大全(笔记本电脑快捷键大全常用)
苹果恢复出厂设置(苹果恢复出厂设置还能恢复数据吗)

首先打开手机上面的“设置”功能,进入手机的系统设置。进入手机的设置后,选择“通用"。进入通用之后,往下滑动页面,在页面的最下方可以看到“还原”的选项,点击进入。进入还原之后,有多个还原选项,我...

路由器的配置步骤(路由器配置教学)

打开浏览器-输入192.168.1.1(一般路由器地址是这个或者查看路由器背面的登录信息)进路由-输入用户名,密码,(默认一般是admin)。2、在【设置向导】里,选择【PPOE拨号】(有些是ADS...

psp模拟器ios(psp模拟器ios推荐)

psp手机模拟器推荐PPSSPP,作为最流行的开源PSP模拟器,因为其强大的功能和兼容性广受玩家们喜爱。虽然提供了PC和安卓双平台的支持,但是有碍于安卓设备的硬件,移动端PPSSPP的功能并不完整。不...

台式机重装系统按f几(重装电脑系统按f几)

F8、F9、F10、F11、F12、F2、del。一般用到这几个。下面以联想电脑装WIN10系统为例:1、将制作好的U盘插入要重装系统的电脑,开机画面出现电脑品牌logo时,不停地按“f2键”进入“B...

win10激活错误代码0x8007007b

Win10激活出现0x8007007b解决方法如下1、找到计算机,右键点击属性,确认你的电脑系统是否是windows10。2、鼠标右击桌面,依次点击个性化-主题-桌面图标设置,勾选计算机后依次点击应用...

4000台式电脑最好的组装配置
4000台式电脑最好的组装配置

四千元价格组装电脑主机与五千元组装电脑主机的价格类似,因为电脑主机就几个大部件,电脑主机主板是多少代的产品?主板内存的插槽数?电脑处理器等如果是自己组装,都可以配置到十二代产品,电脑硬盘可以分为256G固态硬盘做系统盘,1T机械硬盘作为工作...

2025-11-06 20:05 liuian

linux是一种什么系统(linux属于什么系统)

Linux,全称GNU/Linux,是一种免费使用和自由传播的类UNIX操作系统,是一个基于POSIX的多用户、多任务、支持多线程和多CPU的操作系统。其内核由林纳斯·本纳第克特·托瓦兹于1991年1...

手机管理大师免费版(手机管理大师极速版)

使用手机“文件管理”打开文件夹时提示访问受限,需要前往“文件”应用查看1.进入手机设置——安全——应用权限——权限/应用2.在手机桌面找到手机管家——权限隐私——应用权限——权限/应用?当然,相对于被...

电脑能开机但是进不去桌面怎么办

打开任务管理器按Ctrl+Shift+Esc打开任务管理器。文件中运行新任务点击文件,运行新任务。输入指令重启桌面输入explorer.exe,点击确定,等待桌面重启完成就可以了。电脑已经是我们生活中...