ArrayList的源码分析

/**

  • Default initial capacity.
  • 初始化容量为10
    */
    private static final int DEFAULT_CAPACITY = 10;
    private static final Object[] EMPTY_ELEMENTDATA = {};
    /**
  • Shared empty array instance used for default sized empty instances. We
  • distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
  • first element is added.
  • */
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    /**
  • The array buffer into which the elements of the ArrayList are stored.
  • The capacity of the ArrayList is the length of this array buffer. Any
  • empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
  • will be expanded to DEFAULT_CAPACITY when the first element is added.
    */
    transient Object[] elementData; // non-private to simplify nested class access
    /**
  • The size of the ArrayList (the number of elements it contains).
  • @serial
    */
    private int size;
    //最大数组大小
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    //默认实例为一个空数组
    public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
    //添加元素
    public boolean add(E e) {
    //确定容量
    ensureCapacityInternal(size + 1); // Increments modCount!!
    elementData[size++] = e;
    return true;
    }

    private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }

    private void ensureExplicitCapacity(int minCapacity) {
    modCount++;

    // overflow-conscious code
    //超过扩容
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);

    }
    private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    //扩容方式 旧容量+旧容量右移一位
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
    newCapacity = 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);
    }
    //循环清除
    public void clear() {
    modCount++;

    // clear to let GC do its work
    for (int i = 0; i < size; i++)
        elementData[i] = null;
    
    size = 0;

    }
    //删除 --很巧妙的删除
    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;

    }

原文地址:https://blog.51cto.com/mufeng219/2433635

时间: 2024-10-30 00:54:59

ArrayList的源码分析的相关文章

ArrayList部分源码分析(基于1.8)

今天分析第一个集合类:ArrayList 首先,说一下我读这部分源码的感受. ArrayList类底层实现实际上是数组,因此很多操作会调用很多本地(Native)方法来实现或者部分实现.用java实现的很多方法中,只是用java代码进行了一些必要的逻辑判断和变量值的改变. 在AbstractList中加入的modCount变量是为了配合迭代器的使用. 下面是部分源码分析: package java.util; import java.util.function.Consumer; import

Java——ArrayList底层源码分析

1.简介 ArrayList 是最常用的 List 实现类,内部是通过数组实现的,它允许对元素进行快速随机访问.数组的缺点是每个元素之间不能有间隔, 当数组大小不满足时需要增加存储能力,就要将已经有数组的数据复制到新的存储空间中. 当从 ArrayList 的中间位置插入或者删除元素时,需要对数组进行复制.移动.代价比较高.因此,它适合随机查找和遍历,不适合插入和删除. 线性表的顺序存储,插入删除元素的时间复杂度为O(n),求表长以及增加元素,取第 i 元素的时间复杂度为O(1). ArrayL

ArrayList&lt;E&gt;源码分析

ArrayList是按照线性表结构实现的 ArrayList的主要继承结构 public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable public interface List<E> extends Collection<E> public interface Collect

ArrayList的源码分析(基于jdk1.8)

1.初始化 transient Object[] elementData; //实际存储元素的数组 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; public ArrayList() { //初始化为一个默认的空数组 this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } 2. 添加元素 private static final int DEFAU

Vector和Stack源码分析/List集合的总结

序言 这篇文章算是在这list接口下的集合的最后一篇了,前面ArrayList.LinkedList都已经讲解完了,剩下就Vector和Vector的子类Stack啦.继续努力.一步一个脚印, --WH 扩展 学习vector,需要一些多线程的知识,这里比较杂,主要讲解一下等会会用到的 1.锁机制:对象锁.方法锁.类锁 对象锁就是方法锁:就是在一个类中的方法上加上synchronized关键字,这就是给这个方法加锁了. 类锁:锁的是整个类,当有多个线程来声明这个类的对象的时候将会被阻塞,直到拥有

Java集合源码分析之LinkedList

1. LinkedList简介 public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable 可以看到LinkedList类继承AbstractSequentialList类,实现了List, Deque, Cloneable, java.io.Serializable接口.实

2、JDK8中的HashMap实现原理及源码分析

本篇提纲.png 本篇所述源码基于JDK1.8.0_121 在写上一篇线性表的文章的时候,笔者看的是Android源码中support24中的Java代码,当时发现这个ArrayList和LinkedList的源码和Java官方的没有什么区别,然而在阅读HashMap源码的时候,却发现Android中的Java与官方版的出入略大,遂不得不转而用Eclipse导入jdk源码阅读,这里不得不吐槽一句,用惯了IDEA的快捷键,Eclispe还真是用不习惯~~好了,接下来我们言归正传: 一.什么是Has

JAVA Collection 源码分析(一)之ArrayList

到今天为止,差不多已经工作一年了,一直在做的是javaweb开发,一直用的是ssh(sh)别人写好的框架,总感觉自己现在高不成低不就的,所以就像看看java的源码,顺便学习一下大牛的思想和架构,read and write一直是提高自己编程水平的不二法门,写博客只是记录自己的学习历程,方便回顾,写的不好的地方,请多多包含,不喜勿喷,好了废话少说,现在让我们开始我们的历程把,Let's go!!!!!!!! 想看源码无从下手,不知道有没有跟我一样感觉的人们,今天用Intellij发现了可以找出类与

Java中ArrayList源码分析

一.简介 ArrayList是一个数组队列,相当于动态数组.每个ArrayList实例都有自己的容量,该容量至少和所存储数据的个数一样大小,在每次添加数据时,它会使用ensureCapacity()保证容量能容纳所有数据. 1.1.ArrayList 的继承与实现接口 ArrayList继承于AbstractList,实现了List, RandomAccess, Cloneable, java.io.Serializable这些接口. public class  ArrayList<E> ex