1. ArrayList是按照线性表结构实现的
  2. ArrayList的主要继承结构
  3. public class ArrayList<E> extends AbstractList<E>
  4. implements List<E>, RandomAccess, Cloneable, java.io.Serializable
  5.  
  6. public interface List<E> extends Collection<E>
  7.  
  8. public interface Collection<E> extends Iterable<E>
  9.  
  10. public interface Iterable<T>

1.属性

  1. private static final long serialVersionUID = 8683452581122892189L;//序列化ID
  2.  
  3. private static final int DEFAULT_CAPACITY = ;//默认初始化数组的长度是10
  4.  
  5. private static final Object[] EMPTY_ELEMENTDATA = {};//空数组,在构造时,如果参数是0,就用它
  6.  
  7. private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//空数组,在构造时,如果没有参数,就用它
  8.  
  9. transient Object[] elementData; //arrayList存放数据的数组
  10.  
  11. //将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。
  12.  
  13. private int size; //arrayList的长度 默认是0

2.构造器

提供了3个构造器

  1. //指定数组默认初始化的长度
    //如果大于0,就创建一个指定长度的数组
    //如果等于0,就默认是一个空数组
    public ArrayList(int initialCapacity) {
  2. if (initialCapacity > ) {
  3. this.elementData = new Object[initialCapacity];
  4. } else if (initialCapacity == ) {
  5. this.elementData = EMPTY_ELEMENTDATA;
  6. } else {
  7. throw new IllegalArgumentException("Illegal Capacity: "+
  8. initialCapacity);
  9. }
  10. }
  11.  
  12. //如果不指定任何参数,就默认是一个空数组
  13. public ArrayList() {
  14. this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
  15. }

  16. //把其他的Collection对象放到它这里,如果长度是0,就指定一个空数组;否则把传入对象的所有数据一一拷贝到新数组里
  17. public ArrayList(Collection<? extends E> c) {
  18. elementData = c.toArray();
  19. if ((size = elementData.length) != ) {
  20. // c.toArray might (incorrectly) not return Object[] (see 6260652)
  21. if (elementData.getClass() != Object[].class)
  22. elementData = Arrays.copyOf(elementData, size, Object[].class);
  23. } else {
  24. // replace with empty array.
  25. this.elementData = EMPTY_ELEMENTDATA;
  26. }
  27. }

3.添加数据

动态扩容策略

  1. public boolean add(E e) {
  2. ensureCapacityInternal(size + ); //先给数组扩容,如果空间够用,就不用扩;否则按照一定的策略进行扩容
  3. elementData[size++] = e;
  4. return true;
  5. }
  6.  
  7. private void ensureCapacityInternal(int minCapacity) {
  8.  
  9.     //如果当前的数组是DEFAULTCAPACITY_EMPTY_ELEMENTDATA,就初始化数组的长度 = MAX(10 , size+1)
  1.     //使用数组DEFAULTCAPACITY_EMPTY_ELEMENTDATA时,说明使用的是没有参数的构造器
  1. if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
  2. minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
  3. }
  4. //最后给数组扩容
    ensureExplicitCapacity(minCapacity);
  5. }
  6. private void ensureExplicitCapacity(int minCapacity) {
  7. modCount++;
  8.      // overflow-conscious code
  9. if (minCapacity - elementData.length > )
  10. grow(minCapacity);
  11. }
  12.  
  13. private void grow(int minCapacity) {
  14. // overflow-conscious code
  15. int oldCapacity = elementData.length;
  16. int newCapacity = oldCapacity + (oldCapacity >> );//数组扩容策略:增加原数组长度左移位(oldCapacity >> 1)也就是oldCapacity/2
  17. if (newCapacity - minCapacity < )//如果新增的数组长度还是小于数据的个数,就把新数组的长度(newCapacity)等于数据的个数(minCapacity)
  18. newCapacity = minCapacity;
  19. if (newCapacity - MAX_ARRAY_SIZE > )//如果新数组的长度大于最大数组长度说明数组的长度也忒大了,就启动超级扩容策略hugeCapacity()
           newCapacity = hugeCapacity(minCapacity);
  1. // minCapacity is usually close to size, so this is a win:
  2. elementData = Arrays.copyOf(elementData, newCapacity);//最后按照newCapacity的长度,把原先的数据拷贝到新数组
  3. }
  4. private static int hugeCapacity(int minCapacity) {
  5. if (minCapacity < ) // overflow
  6. throw new OutOfMemoryError();
  7. return (minCapacity > MAX_ARRAY_SIZE) ?
  8. Integer.MAX_VALUE : //2147483647
  9. MAX_ARRAY_SIZE; //2147483639
  10.     //数组的最大长度就是Integer.MAX_VALUE(2147483647),但链表的长度是无限的
  11. }
  12. private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
  13. /****************************************************************/
  14. Arrays.class:

    public static int[] copyOf(int[] original, int newLength) {
      int[] copy = new int[newLength];
      System.arraycopy(original, 0, copy, 0,
      Math.min(original.length, newLength));
      return copy;
    }

  1.  

4.整理数组

  1. //如果当前数组的长度大于数据存放的长度,那么就把当前数组换成新数组( 按照数据存放的长度重新创建的数组,然后把数据放到新数组里 )
    //这样能有效节省数组空间
    public void trimToSize() {
  2. modCount++;
  3. if (size < elementData.length) {
  4. elementData = (size == )
  5. ? EMPTY_ELEMENTDATA
  6. : Arrays.copyOf(elementData, size);
  7. }
  8. }

ArrayList<E>源码分析的更多相关文章

  1. Java集合干货——ArrayList源码分析

    ArrayList源码分析 前言 在之前的文章中我们提到过ArrayList,ArrayList可以说是每一个学java的人使用最多最熟练的集合了,但是知其然不知其所以然.关于ArrayList的具体 ...

  2. ArrayList 源码分析

    ArrayList 源码分析 1. 结构   首先我们需要对 ArrayList 有一个大致的了解就从结构来看看吧. 1. 继承   该类继承自 AbstractList 这个比较好说 2. 实现 这 ...

  3. ArrayList源码分析超详细

    ArrayList源码分析超详解 想要分析下源码是件好事,但是如何去进行分析呢?以我的例子来说,我进行源码分析的过程如下几步: 找到类:利用 IDEA 找到所需要分析的类(ztrl+N查找ArraLi ...

  4. Java - ArrayList源码分析

    java提高篇(二一)-----ArrayList 一.ArrayList概述 ArrayList是实现List接口的动态数组,所谓动态就是它的大小是可变的.实现了所有可选列表操作,并允许包括 nul ...

  5. java集合系列之ArrayList源码分析

    java集合系列之ArrayList源码分析(基于jdk1.8) ArrayList简介 ArrayList时List接口的一个非常重要的实现子类,它的底层是通过动态数组实现的,因此它具备查询速度快, ...

  6. ArrayList源码分析超详细(转载)

    ArrayList源码分析超详细   ArrayList源码分析超详解 想要分析下源码是件好事,但是如何去进行分析呢?以我的例子来说,我进行源码分析的过程如下几步: 找到类:利用 IDEA 找到所需要 ...

  7. ArrayList源码分析--jdk1.8

    ArrayList概述   1. ArrayList是可以动态扩容和动态删除冗余容量的索引序列,基于数组实现的集合.  2. ArrayList支持随机访问.克隆.序列化,元素有序且可以重复.  3. ...

  8. Java ArrayList源码分析(有助于理解数据结构)

    arraylist源码分析 1.数组介绍 数组是数据结构中很基本的结构,很多编程语言都内置数组,类似于数据结构中的线性表 在java中当创建数组时会在内存中划分出一块连续的内存,然后当有数据进入的时候 ...

  9. Java入门系列之集合ArrayList源码分析(七)

    前言 上一节我们通过排队类实现了类似ArrayList基本功能,当然还有很多欠缺考虑,只是为了我们学习集合而准备来着,本节我们来看看ArrayList源码中对于常用操作方法是如何进行的,请往下看. A ...

  10. Java ArrayList源码分析(含扩容机制等重点问题分析)

    写在最前面 这个项目是从20年末就立好的 flag,经过几年的学习,回过头再去看很多知识点又有新的理解.所以趁着找实习的准备,结合以前的学习储备,创建一个主要针对应届生和初学者的 Java 开源知识项 ...

随机推荐

  1. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(12)-系统日志和异常的处理②

    系列目录 上一讲我们做了日志与异常的结果显示列表,这一节我们讲要把他应用系统中来. 首先我们在App.Common类库中创建一个通用类ResultHelper,这个类里面写了,获取一个GUID,获取当 ...

  2. 从零开始编写自己的C#框架(1)——前言

    记得十五年前自学编程时,拿着C语言厚厚的书,想要上机都不知道要用什么编译器来执行书中的例子.十二年前在大学自学ASP时,由于身边没有一位同学和朋友学习这种语言,也只能整天混在图收馆里拼命的啃书.而再后 ...

  3. ISO日期格式标准,浏览器到服务器到mysql中的时区

    时区简单理解 https://zh.wikipedia.org/wiki/%E6%97%B6%E5%8C%BA 上面的链接是时区的wiki说明,下面说说我记住的部分: GMT时区是格林威治标准时间,我 ...

  4. 前端精选文摘:BFC 神奇背后的原理

    BFC 已经是一个耳听熟闻的词语了,网上有许多关于 BFC 的文章,介绍了如何触发 BFC 以及 BFC 的一些用处(如清浮动,防止 margin 重叠等).虽然我知道如何利用 BFC 解决这些问题, ...

  5. JSP实现word文档的上传,在线预览,下载

    前两天帮同学实现在线预览word文档中的内容,而且需要提供可以下载的链接!在网上找了好久,都没有什么可行的方法,只得用最笨的方法来实现了.希望得到各位大神的指教.下面我就具体谈谈自己的实现过程,总结一 ...

  6. Sass学习笔记之入门篇

    Sass又名SCSS,是CSS预处理器之一,,它能用来清晰地.结构化地描述文件样式,有着比普通 CSS 更加强大的功能. Sass 能够提供更简洁.更优雅的语法,同时提供多种功能来创建可维护和管理的样 ...

  7. Node.js 给前端带来了什么

    在软件开发领域,前端工程师曾经是一个比较纠结的职业.在Web技术真正发展起来之前的相当长一段时间里,由于技术门槛很低,前端工程师行业一直是鱼龙混杂的状态.其中很多号称是Web开发者的人实际上并没有什么 ...

  8. 类型基础---CLR Via C#笔记一

    一.所有类型都是从System.Obejct派生 1.下面两个类型定义是完全一致的: class Employee{ ... } class Employee:System.Object{ ... } ...

  9. Kafka资源汇总

    终于下定决心写一点普及类的东西.很多同学对Kafka的使用很感兴趣.如果你想参与到Kafka的项目开发中,很多资源是你必须要提前准备好的.本文罗列了一些常用的Kafka资源,希望对这些develope ...

  10. GridView/DataGrid行单击和双击事件实现代码_.Net教程

    功能: 单击选中行,双击打开详细页面 说明:单击事件(onclick)使用了 setTimeout 延迟,根据实际需要修改延迟时间 ;当双击时,通过全局变量 dbl_click 来取消单击事件的响应  ...