2019独角兽企业重金招聘Python工程师标准>>>

ArrayList的数据结构

ArrayList是一种线性数据结构,底层是动态数组实现的,与java中的数组相比,它的容量可以动态添加。

ArrayList的类结构

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

ArrayList的主要成员变量

//默认容量
private static final int DEFAULT_CAPACITY = 10;private static final Object[] EMPTY_ELEMENTDATA = {};private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//ArrayList存储数据的数组
transient Object[] elementData;//存储元素数目
private int size;//默认最大容量数目
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;//
protected transient int modCount = 0;

ArrayList的构造方法

public ArrayList() {this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}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);}
}

ArrayList的主要方法

    存:

    boolean add(E e);

public boolean add(E e) {//根据当前下角标size+1和当前数组的容量,判断是否需要扩容,如果需要,扩容到1.5倍ensureCapacityInternal(size + 1);  // Increments modCount!!//将新元素加入数组中,下角标为size+1elementData[size++] = e;return true;
}private void ensureCapacityInternal(int minCapacity) {if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//如果存储元素的数组为空,容量值为10和minCapacity中的较大者minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);}ensureExplicitCapacity(minCapacity);
}private void ensureExplicitCapacity(int minCapacity) {//更新次数加一modCount++;// overflow-conscious codeif (minCapacity - elementData.length > 0)//如果minCapacity大于当前数组的长度,扩容grow(minCapacity);
}private void grow(int minCapacity) {//将当前数组的长度赋值给oldCapacityint oldCapacity = elementData.length;//新的容量值为原来的1.5倍int newCapacity = oldCapacity + (oldCapacity >> 1);if (newCapacity - minCapacity < 0)//如果新容量值比minCapacity 值小,新容量值即为minCapacitynewCapacity = minCapacity;if (newCapacity - MAX_ARRAY_SIZE > 0)//如果新容量值大于允许的最大长度newCapacity = hugeCapacity(minCapacity);//根据容量创建一个新数组,并将旧数组的元素复制给新数组elementData = Arrays.copyOf(elementData, newCapacity);
}private static int hugeCapacity(int minCapacity) {if (minCapacity < 0) // overflow//如果minCapacity小于零,直接抛出OOM异常throw new OutOfMemoryError();//如果minCapacity大于最大数组容量,则返回Integer的最大值,否则返回return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;
}

    

    void add(int index,E e);

public void add(int index, E element) {//校验下角标index是否越界rangeCheckForAdd(index);//判断是否需要扩容ensureCapacityInternal(size + 1);  // Increments modCount!!//将当前数组中下角标为[index,size]的元素复制到[index+1,size+1]的位置System.arraycopy(elementData, index, elementData, index + 1,size - index);//将element放置到数组下角标为index的位置elementData[index] = element;//数组内元素个数加1size++;
}private void rangeCheckForAdd(int index) {if (index > size || index < 0)//如果index大于数组元素的个数,或者index<0,抛出下角标越界异常throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

E  set(int index,E e);

public E set(int index, E element) {//校验下角标是否越界rangeCheck(index);//将数组中下角标为index的元素赋值给oldValueE oldValue = elementData(index);//再将新元素放置到下角标index位置elementData[index] = element;//返回旧值return oldValue;
}

取:

    E get(int index);

public E get(int index) {//校验下角标是否越界rangeCheck(index);//返回数组中下角标为index的元素return elementData(index);
}private void rangeCheck(int index) {if (index >= size)throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

移除:

E remove(int index);通过下角标移除。

public E remove(int index) {//判断下角标是否越界rangeCheck(index);//修改次数加一modCount++;//将数组中下角标为index的元素赋值给oldValueE oldValue = elementData(index);//要移动的元素个数int numMoved = size - index - 1;if (numMoved > 0)//如果要移动的元素个数大于0,移动// 将elementData数组index+1位置开始拷贝到elementData从index开始的空间 System.arraycopy(elementData, index+1, elementData, index,numMoved);//最后一个元素设为null,并将size-1elementData[--size] = null; // clear to let GC do its work返回旧值return oldValue;
}

boolean remove(Object o);移除指定元素

public boolean remove(Object o) {if (o == null) {//如果要移除的元素为null//循环遍历数组for (int index = 0; index < size; index++)if (elementData[index] == null) {//如果某个下角标的元素为null//移除该下角标的元素fastRemove(index);return true;}} else {//循环遍历数组for (int index = 0; index < size; index++)if (o.equals(elementData[index])) {//如果某个下角标的元素为o移除该下角标的元素fastRemove(index);return true;}}return false;
}private void fastRemove(int index) {//修改次数加一modCount++;//要移动的元素个数int numMoved = size - index - 1;if (numMoved > 0)// 将elementData数组index+1位置开始拷贝到elementData从index开始的空间 System.arraycopy(elementData, index+1, elementData, index,numMoved);elementData[--size] = null; // clear to let GC do its work
}

转载于:https://my.oschina.net/u/3765527/blog/1828334

Jdk8集合源码解析---ArrayList相关推荐

  1. 源码 解析_最详细集合源码解析之ArrayList集合源码解析

    从今天开始我会将集合源码分析陆陆续续整理,写成文章形成集合源码系列文章,方便大家学习 ArrayList集合源码其实相对比较简单,整个源码结构相对于HashMap等源码要好理解的多:先来看下Array ...

  2. Java集合系列---List源码解析(ArrayList和LinkedList的区别)

    List源码主要讲ArrayList,LinkedList,Vector三个类 1 ArrayList ArrayList是一个底层基于数组的集合, 首先来看一下它的继承关系, public clas ...

  3. list最大容量_Java 基础(四)集合源码解析 List

    List 接口 前面我们学习了Iterator.Collection,为集合的学习打下了基础,现在我们来学习集合的第一大体系 List. List 是一个接口,定义了一组元素是有序的.可重复的集合. ...

  4. lamda获取参数集合去空_集合源码解析之LinkedList

    在日常开发中,最常用的List是ArrayList其次便是LinkedList了.上次我们已经研究过了ArrayList,今天来深入学习下LinkedList... 概述 LinkedList顾名思义 ...

  5. Java集合源码解析

    文章目录 1.集合包 1.1 ArrayList 实现方式 创建:ArrayList() 插入对象:add(E) 删除对象:remove(E) 获取单个对象:get(int) 遍历对象:iterato ...

  6. JDK8 HashMap源码解析

    1.概述 本篇文章我们来聊聊大家日常开发中常用的一个集合类 - HashMap.HashMap 最早出现在 JDK 1.2中,底层基于散列算法实现.HashMap 允许 null 键和 null 值, ...

  7. JDK8 ThreadLocal 源码解析与最佳实践

    文章目录 用法 Example1 Example2 Springboot @Transcation 注解的原理 Entry 的 Key 设置为弱引用有什么好处 内存泄漏问题 This class pr ...

  8. Java集合源码解析之ArrayList

    uml类图: 基本简介: ArrayList的底层数据结构是数组,所以内存需要为arrayList保证有足够的连续的内存空间. 添加操作会导致数组扩容,数组扩容比较消耗性能. 非尾部的添加和删除元素操 ...

  9. JDK源码解析--ArrayList

    一.ArrayList简介 ArrayList是用一个数组实现的集合,支持随机访问,元素有序且可以重复. ArrayList是一种变长的集合类,基于定长数组实现. ArrayList允许空值和重复元素 ...

最新文章

  1. Error running query: MetaException(message:Got exception: java.net.ConnectException Call From XXXX
  2. 将来,你会成为这三种程序员之一
  3. 数据库相关中间件介绍
  4. WebRTC视频编解码器性能评估
  5. ubuntu安装VMware出错
  6. 如何以及何时使用例外
  7. php 删除上传文件,php实现文件上传、下载和删除的方法
  8. 图像分类 数据准备(将文件夹中所有图片路径写到TXT文件中)
  9. java 反射基础_Java基础教程:反射基础
  10. 《深入学习 Golang》并发编程
  11. C#GDI绘制自定义字体
  12. 用Eclipse远程调试部署在Tomcat下的Web应用程序
  13. Cesium 已知两点,计算以一个点为圆心,将另一个点旋转一定度数后的新点的坐标/position_A绕position_B逆时针旋转angle度(角度)得到新点 function rotatedPo
  14. 5G+北斗RTK定位:高精度定位技术发展更进一步
  15. 用批处理共享打印机电脑设置
  16. 用 TypeScript 写一个轻量级的 UI 框架之八:表单控件之富文本编辑器
  17. 如何用公式编辑器打半中括号?
  18. linux 无线网卡ping不同,请教高手,本地网卡和无线网卡均不能ping通网关
  19. 芯片前沿 | 云端芯片功耗问题日益严重
  20. AT指令表(中文详解)

热门文章

  1. python accept解析_python中requests库使用方法详解
  2. matlab篮球队需要五名队员,MATLAB应用与数学欣赏.doc
  3. 计算机科学与技术专业综合二,计算机科学与技术专业综合一第二页
  4. 如何更改jupyter notebook默认存储路径
  5. 【 Vivado 】输入延迟约束实例
  6. Verilog: How to avoid 'Redeclaration of ansi port'
  7. 红帽Linux 6.5上配置ASM流程
  8. Eclipse中配置Tomcat
  9. scala之Actors
  10. LinearLayout、RelativeLayout、FrameLayout居中显示