ArrayList

1、ArrayList的特点

相比之前的LinkedList可以实现动态扩容。

2、成员属性

private static final long serialVersionUID = 8683452581122892189L;
//JAVA序列化的机制是通过判断类的serialVersionUID来验证的版本一致的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID于本地相应实体类的serialVersionUID进行比较。如果相同说明是一致的,可以进行反序列化,否则会出现反序列化版本一致的异常。private static final int DEFAULT_CAPACITY = 10;
//默认的数组容量值private static final Object[] EMPTY_ELEMENTDATA = {};
//空的elementData数组private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//无参构造要使用的空对象数组。transient Object[] elementData;
//定义一个Object引用类型数组,存放ArrayList的元素。也是ArrayList操作的主要数组。private int size;
//表示当前ArrayList元素个数,始终小于elementData长度private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
(-8:避免一些机器内存溢出,减少出错几率,所以少分配)
//定义该数组最大容量

3、方法

1、构造方法(三种构造方法)

//无参构造
public ArrayList() {this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;//将定义的空数组赋值给elementData
}//有参构造public ArrayList(int initialCapacity)//指定数组容量{if (initialCapacity > 0) {this.elementData = new Object[initialCapacity];//定义elementData容量} else if (initialCapacity == 0) {this.elementData = EMPTY_ELEMENTDATA;//如果指定容量为0则把定义的空数组赋值给elementData} else //小于0则不满足容量规范,抛出异常并提示非法异常
throw new IllegalArgumentException("IllegalCapacity:"+initialCapacity);}}//还有一种迭代器构造方法(没看懂)

2、动态扩容方法

在每个add方法中会进行一次容量查询,如add中

public boolean add(E e) {ensureCapacityInternal(size + 1);//进行容量查询elementData[size++] = e;return true;
}
//private void ensureCapacityInternal(int minCapacity)//将数组容量+1作为最小容量{ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));}
//private static int calculateCapacity(Object[] elementData, int minCapacity) {if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {return Math.max(DEFAULT_CAPACITY, minCapacity);}//当无参构造执行后,第一次调用add方法增加时,执行到这就会将最小容量变为10return minCapacity;}
//private void ensureExplicitCapacity(int minCapacity) {modCount++;if (minCapacity - elementData.length > 0)//如果最小容量大于数组容量则会执行扩容方法grow(minCapacity);}
//private void grow(int minCapacity) {int oldCapacity = elementData.length;//记录下当前数组的容量int newCapacity = oldCapacity + (oldCapacity >> 1);//定义新的数组容量为当前数组容量的1.5倍if (newCapacity - minCapacity < 0)newCapacity = minCapacity;//如果增大后的新的数组容量小于于最小容量则把最小容量作为新的数组容量if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);//如果新的数组容量大于该数组最大容量elementData = Arrays.copyOf(elementData, newCapacity);//将elementData容量扩容成newCapacity之后返回给elementData//主要实现是通过Arrays.copyOf()方法}
//public static <T> T[] copyOf(T[] original, int newLength) {return (T[]) copyOf(original, newLength, original.getClass());}
//public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {@SuppressWarnings("unchecked")T[] copy = ((Object)newType == (Object)Object[].class)? (T[]) new Object[newLength]: (T[]) Array.newInstance(newType.getComponentType(), newLength);System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));return copy;}
//private static int hugeCapacity(int minCapacity) {if (minCapacity < 0)//如果最小容量小于0则抛出异常throw new OutOfMemoryError();return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;//如果最小容量大于定义的最大数组容量则返回Integer类型的最大值 否则还是返回Integer最大值2的31次方-1}

add方法在实现动态扩容后就会将参数赋值给数组的相应位置。其他add方法也都是先对容量进行检查然后拷贝数组。

3、remove方法

    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 workreturn oldValue;}
//private void fastRemove(int index) {modCount++;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}

当我们调用 remove(int index) 时,首先会检查 index 是否合法,然后再判断要删除的元素是否位于数组的最后一个位置。如果 index 不是最后一个,就再次调用 System.arraycopy() 方法拷贝数组。说白了就是将从 index + 1 开始向后所有的元素都向前挪一个位置。然后将数组的最后一个位置空,size - 1。如果 index 是最后一个元素那么就直接将数组的最后一个位置空,size - 1即可。 当我们调用 remove(Object o) 时,会把 o 分为是否为空来分别处理。然后对数组做遍历,找到第一个与 o 对应的下标 index,然后调用 fastRemove 方法,删除下标为 index 的元素。 fastRemove(int index) 方法和 remove(int index) 方法基本全部相同。

4、clear方法

public void clear() {modCount++;// clear to let GC do its workfor (int i = 0; i < size; i++)elementData[i] = null;size = 0;
}

就是将数组的元素逐个赋值为空。

5、toArrat方法

顾名思义就是把list变成一个Object数组

public Object[] toArray() {return Arrays.copyOf(elementData, size);//copyOf方法
}

第二个方法可以把list变成你需要的类型数组

public <T> T[] toArray(T[] a) {if (a.length < size)// Make a new array of a's runtime type, but my contents:return (T[]) Arrays.copyOf(elementData, size, a.getClass());System.arraycopy(elementData, 0, a, 0, size);if (a.length > size)a[size] = null;return a;
}

6、其他方法

set方法:
public E set(int index, E element) {rangeCheck(index);//检查索引是否越界E oldValue = elementData(index);//将旧值保存elementData[index] = element;//赋新值return oldValue;//返回旧值
}
indexOf方法:
// 从首开始查找数组里面是否存在指定元素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;}
get方法:
public E get(int index) {rangeCheck(index);//检查索引是否越界return elementData(index);
}
//E elementData(int index) {return (E) elementData[index];//返回该数组中的索引位置的值}

Arraylist理解相关推荐

  1. ArrayList理解(5)与vector区别

    前几篇文章我们重点说了ArrayLIst,是时候放出这张图了. 这张图里的内容对我们学习Java来说,非常的重要,白色的部分是需要去了解的,黄色部分是我们要去重点了解的,不但要知道怎么去用,至少还需要 ...

  2. Arraylist理解(2)扩容

    我们先回顾一下之前的所说过的数组,话不多说,上代码: 老规则,我们继续画一画,加深一下印象,上图: 这个图我们去掉了ArrayList初探 - 知乎专栏 一文图里那些无用的细节(方法区,常量池等),方 ...

  3. Arraylist理解(3)删除元素

    第三次强调,ArrayLIst是一个普通的类. 好,现在我们来讨论一下数组的删除,我们知道数组一但在堆内存中创建出来,数组长度是不可变的,看以下源码: 添加10个用户 比如我们要把"周八&q ...

  4. ArrayList理解(1)初始化

    ArrayList初始化 首先ArrayList是一个普通的类,我们来看一段代码: 首先:执行List<Person> list1 = new ArrayList<>();当看 ...

  5. 深入理解java中的ArrayList和LinkedList

    杂谈最基本数据结构--"线性表": 表结构是一种最基本的数据结构,最常见的实现是数组,几乎在每个程序每一种开发语言中都提供了数组这个顺序存储的线性表结构实现. 什么是线性表? 由0 ...

  6. 深入理解ArrayList

    ArrayList可以说是Java开发中最常用的集合容器了,今天就来分析一下ArrayList的源码和注意点,可以更加深入的理解ArrayList实现原理. 文章目录 概述 常用方法 源码分析 Arr ...

  7. java arraylist length,在Java中调整ArrayList的大小时,无法理解溢出的可能性

    来自JDK 7 java.util.ArrayList类的引用代码片段让我感到困惑.我不能为我的生活理解它怎么可能导致溢出.我困惑的地方标有< ---这是什么意思?有人可以帮助我理解这种逻辑可能 ...

  8. java arraylist 实现原理_Java进阶--深入理解ArrayList实现原理

    编辑推荐: 文章主要介绍ArrayList的继承关系,ArrayList的方法使用和源码解析,它提供了动态的增加和减少元素,实现了Collection和List接口,可以灵活的设置数组的大小,希望对您 ...

  9. arraylist如何检测某一元素是否为空_我们应该如何理解Java集合框架的关键知识点?...

    以下介绍经常使用的集合类,这里不介绍集合类的使用方法,只介绍每个集合类的用途和特点,然后通过比较相关集合类的不同特点来让我们更深入的了解它们. Collection接口 Collection是最基本的 ...

最新文章

  1. win10下Anaconda如何查看PyTorch版本
  2. SharedActivityContext要引用那个单元?
  3. 预算里怎样计算机械作业费,用实物法编制施工图预算的完整步骤有( )等。 A.计算工程量B.套用预算人工、材料、机械 - 作业在线问答...
  4. 1命名规则 sentinel_Sentinel 实战-限流篇
  5. 苹果爸爸发飙,封杀 React Native?
  6. 《数学之美》—信息的度量和作用
  7. 语音识别系统原理介绍----gmm-hmm
  8. 腾讯在线QQ代码和实现原理
  9. 蓝星实物微商城H5源码 附搭建教程
  10. php网页弹窗广告,弹窗广告最多的网站
  11. Linux虚拟机如何扩展内存盘
  12. python相关性分析的散点图怎么做_相关性分析 散点图
  13. 关于PTC保险丝工作原理总结
  14. 2021年的学习Flag:只争朝夕,不负韶华
  15. 时空超分辨论文阅读笔记(一)---- Zooming Slow-Mo
  16. org.springframework.util.AntPathMatcher:URL 与 匹配规则
  17. 虚拟服务器和vdi,比较瘦客户端和VDI
  18. Android通信安全之HTTPS
  19. 双网卡的网络路由配置
  20. R语言:特殊数据类型S4

热门文章

  1. 零基础学浙大翁恺C语言(1):Dev C++的安装与第一个小程序
  2. 【分享】用Canvas实现画板功能
  3. 高并发系统设计十一(缓存加速)
  4. get token failed, com.huawei.hms.common.ApiException: 907135702: certificate fingerprint empty
  5. 逻辑思维不好能学java吗_没思维能力怎么学java?
  6. 复习步骤26-30 DMN(2)运行第一个DMN应用
  7. 【物理应用】Matlab 二维对流扩散温度场
  8. java se me ee 的基本概念
  9. 集美大学诚毅学院传一科技杯《消灭星星》
  10. C#mir2- Encoding.GetEncoding(euc-kr));学习 Encoding.