可增长数组结构

实现:
  1. 内部采用数组的方式。
    1.1 添加元素,会每次校验容量是否满足, 扩容规则是当前数组长度+当前数组长度的二分之一。容量上限是Integer.MAX_VALUE。 copy使用Arrays.copy的api
    1.2 删除元素
      1.2.1 通过对象删除。遍历数组,删除第一个匹配的对象
      1.2.3 通过下标删除。判断下标是否越界。
        使用 System.arraycopy进行copy, 并将元素的最后一位设置为null.供gc回收
  2. 内部是同步[modCount]
    2.1 ArrayList数据结构变化的时候,都会将modCount++。
    2.2 采用Iterator遍历的元素, next()会去检查集合是否被修改[checkForComodification],如果集合变更会抛出异常
    类似于数据库层面的 乐观锁 机制。 可以通过 Iterator的api去删除元素
3. 数组结构,内部存储数据是有序的,并且数据可以为null,支持添加重复数据

modCount作用:
https://www.cnblogs.com/zuochengsi-9/p/7050351.html

源码分析

package xin.rtime.collections.list;import java.util.Arrays;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;// 模拟ArrayList的实现
public class ArrayList<E> {private transient int modCount = 0;    // 修改次数private transient Object[] elementData; // 数据集合private static final Object[] EMPTY_ELEMENTDATA = {}; // 默认空数组private int size; // 数组实际个数private static final int DEFAULT_CAPACITY = 10; // 默认长度private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;  // 数组最大长度// 默认构造函数public ArrayList() {elementData = EMPTY_ELEMENTDATA; // 默认等于空集合
    }// 初始化指定长度public ArrayList(int initialCapacity) {if (initialCapacity < 0) // 长度小于0 抛异常throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);this.elementData = new Object[initialCapacity]; // new一个指定长度的对象数组
    }// 添加元素public boolean add(E e) {ensureCapacityInternal(size + 1);elementData[size++] = e; // 放置添加的元素return true;}// 删除元素public boolean remove(E e) {if (e == 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 (e.equals(elementData[index])) {   // eqals比较
                    fastRemove(index);return true;}}return false;}private void fastRemove(int index) {modCount++;int numMoved = size - index - 1;      // 当前size - index - 1    数组从0开始if (numMoved > 0)System.arraycopy(elementData, index+1, elementData, index,numMoved);   // system arraycopyelementData[--size] = null; // clear to let GC do its work   gc回收
    }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;}// 获取元素public E get(int index) {rangeCheck(index);   // index校验return elementData(index);}@SuppressWarnings("unchecked")E elementData(int index) {return (E) elementData[index];}private void rangeCheck(int index) {if (index >= size)throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}private String outOfBoundsMsg(int index) {return "Index: "+index+", Size: "+size;}// 返回元素个数public int size() {return size;}// 判断当前容量是否能否装下元素private void ensureCapacityInternal(int minCapacity) {if (elementData == EMPTY_ELEMENTDATA) // 空集合minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); // 10 传入的
ensureExplicitCapacity(minCapacity);}// 提供外部遍历public Iterator<E> iterator() {return new Itr();}private class Itr implements Iterator<E> {int cursor;       // index of next element to return    游标int lastRet = -1; // index of last element returned; -1 if no such    最后元素下标int expectedModCount = modCount;  // 当前数组修改次数public boolean hasNext() {return cursor != size;  // 当前游标是否等于size
        }@SuppressWarnings("unchecked")public E next() {checkForComodification();   // 检查数组是否被操作过int i = cursor;if (i >= size)throw new NoSuchElementException();Object[] elementData = ArrayList.this.elementData;if (i >= elementData.length)throw new ConcurrentModificationException();cursor = i + 1;return (E) elementData[lastRet = i];}public void remove() {if (lastRet < 0)throw new IllegalStateException();checkForComodification();  // 检查集合是否被操作过try {ArrayList.this.remove(lastRet);cursor = lastRet;lastRet = -1;expectedModCount = modCount;} catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();}}final void checkForComodification() {if (modCount != expectedModCount)throw new ConcurrentModificationException();}}// 判断容量 扩容private void ensureExplicitCapacity(int minCapacity) {modCount++;  // 修改+1if (minCapacity - elementData.length > 0) // 当前长度 大于 数组长度
            grow(minCapacity);}public void add(int index, E element) {rangeCheckForAdd(index);ensureCapacityInternal(size + 1);  // Increments modCount!!System.arraycopy(elementData, index, elementData, index + 1,size - index);elementData[index] = element;size++;}private void rangeCheckForAdd(int index) {if (index > size || index < 0)   // index 超出 size  或者  index 小于0 ---> 数组越界throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}public E set(int index, E element) {rangeCheck(index);   // 校验index是否满足
E oldValue = elementData(index);elementData[index] = element;return oldValue;}/**<<      :     左移运算符,num << 1,相当于num乘以2>>      :     右移运算符,num >> 1,相当于num除以2>>>    :     无符号右移,忽略符号位,空位都以0补齐*/// 扩容private void grow(int minCapacity) {int oldCapacity = elementData.length; // 当前数组长度int newCapacity = oldCapacity + (oldCapacity >> 1);  // 新容量大小 = 原来长度 + 原来长度 右移一位,除以2if (newCapacity - minCapacity < 0)  // 新长度 - 传的长度 小于  0newCapacity = minCapacity;   //
        if (newCapacity - MAX_ARRAY_SIZE > 0)  // 当前长度超出最大容量newCapacity = hugeCapacity(minCapacity);// minCapacity is usually close to size, so this is a win:elementData = Arrays.copyOf(elementData, newCapacity);   // 拷贝原来数据
    }// 判断容量private int hugeCapacity(int minCapacity) {if (minCapacity < 0) // overflowthrow new OutOfMemoryError();return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;}}

转载于:https://www.cnblogs.com/LuisYang/p/10034514.html

ArrayList源码学习相关推荐

  1. 集合框架-ArrayList源码学习

    MIT麻省理工学院讲义上的一段话: 如果没有完全理解 JAVA 库中的具有决定性的部分,你就不可能成为一个优秀的 JAVA 程序员.基本类型都包含在 java.lang 中.java.util包提供了 ...

  2. ArrayList源码学习第二天全解

    目录 1,删除元素 1.1,删除单个元素remove 1.2, 移除多个元素removeRange 1.3,移除在 c 中的元素batchRemove 4,移除不在 c 中的元素retainAll 2 ...

  3. JDK源码学习之Arraylist与LinkedList

    ArrayList和LinkedList是我们在开发过程中常用的两种集合类,本文将从底层源码实现对其进行简单介绍. 下图是Java集合类所涉及的类图. 一.ArrayList 从上面的集合类图可以看出 ...

  4. Java 集合系列(2): ArrayList源码深入解析和使用示例

    戳上面的蓝字关注我们哦! 精彩内容 精选java等全套视频教程 精选java电子图书 大数据视频教程精选 java项目练习精选 概要 上一章,我们学习了Collection的架构.这一章开始,我们对C ...

  5. 增加数组下标_数组以及ArrayList源码解析

    点击上方"码之初"关注,···选择"设为星标" 与精品技术文章不期而遇 前言 前一篇我们对数据结构有了个整体的概念上的了解,没看过的小伙伴们可以看我的上篇文章: ...

  6. 面试官系统精讲Java源码及大厂真题 - 05 ArrayList 源码解析和设计思路

    05 ArrayList 源码解析和设计思路 耐心和恒心总会得到报酬的. --爱因斯坦 引导语 ArrayList 我们几乎每天都会使用到,但真正面试的时候,发现还是有不少人对源码细节说不清楚,给面试 ...

  7. JAVA小项目实例源码—学习娱乐小助手

    代码地址如下: http://www.demodashi.com/demo/11456.html 一.程序实现 项目目录: MyJFrame:实现项目界面样式: AppProcess:实现调用api或 ...

  8. 顺序线性表 ---- ArrayList 源码解析及实现原理分析

    原创播客,如需转载请注明出处.原文地址:http://www.cnblogs.com/crawl/p/7738888.html ------------------------------------ ...

  9. JDK源码-ArrayList源码

    1,继承结构图:      -1,ArrayList继承AbstractList抽象类,实现List.RandomAccess.Cloneable.Serializable接口.      -2,查看 ...

最新文章

  1. 决策树算法详解(2)
  2. matlab积分与绘图
  3. oracle 中关于null的操作
  4. 5-29 vscode占位
  5. eclipse maven创建web项目
  6. 嘉实多RO150合成齿轮油
  7. mysql 3种报错_MySQL读取Binlog日志常见的3种错误-阿里云开发者社区
  8. php copy 文件夹,php删除与复制文件夹及其文件夹下所有文件的实现代码
  9. 一步步学习javascript基础篇(8):细说事件
  10. 颜宁谈院士增选:导师施一公让我特别受益的是:纯粹,做事情的纯粹
  11. python 读取 Excel 文件的方法 csv.reader
  12. Android网络类型判断(2g、3g、wifi)
  13. C运行时库(CRT)
  14. 算法求100以内的质数
  15. excel查找窗口被拉边上_excel
  16. 幼儿园调查过程怎么写_幼儿园家长的调查问卷话术
  17. 【日语】日文假名输入与键盘对应
  18. 【Linux】如何将ntfs硬盘挂载到home目录下并具有读写权限
  19. SQL 函数 —— TRUNCATE详解示例
  20. 非会员免费建立QQ群的方法!

热门文章

  1. centos使用镜像源轻松配置golang+vscode的方法
  2. 2022-2028年中国数字化档案加工行业市场深度分析及发展策略分析报告
  3. etcd 笔记(09)— 基于 etcd 实现微服务的注册与发现
  4. 掩码语言模型(Masked Language Model)mlm
  5. Google Colab 免费GPU服务器使用教程 挂载云端硬盘
  6. 第四天:Vue组件的slot以及webpack
  7. NNVM Compiler,AI框架的开放式编译器
  8. 用NumPy genfromtxt导入数据
  9. MindSpore网络模型类
  10. 自主数据类型:在TVM中启用自定义数据类型探索