Java记录 -46- ArrayList源码剖析

在编程中经常会使用到集合,而集合中最常用的是ArrayList。

集合中存放的依然是对象的引用,而不是对象本身,和数组一样。

当我们学习了数组又学习集合时,发现集合很神奇。数组需要在定义的时候声明大小,而ArrayList不用管大小,定义了以后可以随便使用。

查看ArrayList的源代码,可以发现,ArrayList底层是用数组进行存放元素的。ArrayList并不神奇,底层实现是通过一个对象数组Object[]来存放元素,由于是对象数组,所以只能存放对象,并可以存放任何对象。而数组存放了对象的引用,所以ArrayList也存放对象的引用。

ArrayList的两个构造函数:

我们通常使用ArrayList时会使用其不带参数的构造函数,或指定一个容量的参数的构造函数,而其底层实现是不带参数的构造函数会调用带参数的构造函数,只是不带参数的构造函数会默认使用传递一个10参数,带参数的构造函数中会声明一个长度为10的Object数组。

   /**
     * The array buffer into which the elements of the ArrayList are stored.
     * The capacity of the ArrayList is the length of this array buffer.
     */
   private transient Object[] elementData;
   
   public ArrayList(int initialCapacity) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
        this.elementData = new Object[initialCapacity];
    }
    /**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
        this(10);
    }

下面是我们经常使用的add方法,该方法首先会判断底层数组的长度是否大于需要的长度,让将元素放入底层数组中。

    /**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return <tt>true</tt> (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
        ensureCapacity(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

ArrayList的size()方法返回的是集合的大小,其实是底层数组的长度。

ArraList中一个很重要的方法(ArrayList底层是使用数组实现的,为什么它可以无限添加元素呢?)

下面这个方法ensureCapacity做了实现,minCapacity是要追加元素的位置,它和底层数组的大小做比较,如果小于底层数组的长度则什么也不做;重点在大于底层数组长度时,它做了一些事情:将原数组的大小进行扩容,扩多大呢,原数组的3/2+1;然后使用Arrays.copyOf方法,将原数组的元素拷贝到新指定大小的数组里,至此实现数组的扩容。

   /**
     * Increases the capacity of this <tt>ArrayList</tt> instance, if
     * necessary, to ensure that it can hold at least the number of elements
     * specified by the minimum capacity argument.
     *
     * @param   minCapacity   the desired minimum capacity
     */
    public void ensureCapacity(int minCapacity) {
        modCount++;
        int oldCapacity = elementData.length;
        if (minCapacity > oldCapacity) {
            Object oldData[] = elementData;
            int newCapacity = (oldCapacity * 3)/2 + 1;
            if (newCapacity < minCapacity)
                newCapacity = minCapacity;
            // minCapacity is usually close to size, so this is a win:
            elementData = Arrays.copyOf(elementData, newCapacity);
        }
    }
时间: 2024-10-11 03:30:49

Java记录 -46- ArrayList源码剖析的相关文章

Java集合源码剖析——ArrayList源码剖析

ArrayList简介 ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存. ArrayList不是线程安全的,只能用在单线程环境下,多线程环境下可以考虑用Collections.synchronizedList(List l)函数返回一个线程安全的ArrayList类,也可以使用concurrent并发包下的CopyOnWriteArrayList类. ArrayList实现了Serializable接口,因此它支持序列化,能够通过

【Java集合源码剖析】ArrayList源码剖析

转载请注明出处:http://blog.csdn.net/ns_code/article/details/35568011 ArrayList简介 ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存. ArrayList不是线程安全的,只能用在单线程环境下,多线程环境下可以考虑用Collections.synchronizedList(List l)函数返回一个线程安全的ArrayList类,也可以使用concurrent并发包下的C

转:【Java集合源码剖析】ArrayList源码剖析

转载请注明出处:http://blog.csdn.net/ns_code/article/details/35568011   本篇博文参加了CSDN博文大赛,如果您觉得这篇博文不错,希望您能帮我投一票,谢谢! 投票地址:http://vote.blog.csdn.net/Article/Details?articleid=35568011   ArrayList简介 ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存. ArrayL

Java ArrayList源码剖析

转自: Java ArrayList源码剖析 总体介绍 ArrayList实现了List接口,是顺序容器,即元素存放的数据与放进去的顺序相同,允许放入null元素,底层通过数组实现.除该类未实现同步外,其余跟Vector大致相同.每个ArrayList都有一个容量(capacity),表示底层数组的实际大小,容器内存储元素的个数不能多于当前容量.当向容器中添加元素时,如果容量不足,容器会自动增大底层数组的大小.前面已经提过,Java泛型只是编译器提供的语法糖,所以这里的数组是一个Object数组

【源码】ArrayList源码剖析

//-------------------------------------------------------------------- 转载请注明出处:http://blog.csdn.net/chdjj by Rowandjj 2014/8/7 //-------------------------------------------------------------------- 从这篇文章开始,我将对java集合框架中的一些比较重要且常用的类进行分析.这篇文章主要介绍的是Array

ArrayList源码剖析

ArrayList简介 ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存. ArrayList不是线程安全的,只能用在单线程环境下,多线程环境下可以考虑用Collections.synchronizedList(List l)函数返回一个线程安全的ArrayList类,也可以使用concurrent并发包下的CopyOnWriteArrayList类. ArrayList实现了Serializable接口,因此它支持序列化,能够通过

Java HashSet和HashMap源码剖析

转自: Java HashSet和HashMap源码剖析 总体介绍 之所以把HashSet和HashMap放在一起讲解,是因为二者在Java里有着相同的实现,前者仅仅是对后者做了一层包装,也就是说HashSet里面有一个HashMap(适配器模式).因此本文将重点分析HashMap. HashMap实现了Map接口,允许放入null元素,除该类未实现同步外,其余跟Hashtable大致相同,跟TreeMap不同,该容器不保证元素顺序,根据需要该容器可能会对元素重新哈希,元素的顺序也会被重新打散,

Java集合类库 ArrayList 源码解析

集合类库是Java的一个重大突破,方便了我们对大数据的操作.其中 Arrays 和 Collections 工具类可以帮助我们快速操作集合类库.下面对Java集合类库的源码分析是基于jdk1.7的.今天我们来看看ArrayList的底层实现原理. ArrayList的继承结构图 继承自 AbstractList 抽象类,在上层是 AbstractCollection 抽象类,直接去 AbstractCollection 类去看看. AbstractCollection 类主要实现了 Collec

Java 1.8 ArrayList源码解析

1 // 非线程安全 2 // 继承了AbstractList类 3 // 实现了List.RandomAccess.Cloneable.java.io.Serializable接口 4 // 后面3个接口是标记接口,没有抽象方法. 5 // 表示ArrayList可以随机访问.浅复制.序列化和反序列化. 6 public class ArrayList<E> extends AbstractList<E> 7 implements List<E>, RandomAcc

Java类集框架之ArrayList源码剖析

ArrayList 基于数组实现,本质上是对象引用的一个变长数组,能够动态的增加或减小其大小. 不是线程安全的,只能用在单线程环境下.多线程环境下可以考虑用Collection.synchronizedList(List l)函数返回一个线程安全的ArrayList类,也可以使用concurrent并发包下的 CopyOnWriteArrayList类 下面直接贴ArrayList的Java实现,来源JDK1.8.0_25/src.zip. public class ArrayList<E>