• JAVA数据结构——集合之ArrayList


    盗图一张,找不到原作者了,如有知道原链接的朋友,请告知,谢谢。

    java的集合继承关系,第一个让我感觉有些头疼的JAVA知识点,初学时复杂的继承关系让我有点无所适从。今天开始重新梳理自己半年来的知识点,补充体系上的漏洞,个人水平还属于初级阶段,有概念错误或疏漏,也请各位朋友指正与补充,谢谢。

    从List入手,依次梳理各常用数据结构的源码与原理,List下面常用的数据结构有ArrayList、LinkedList、Vector(线程安全,效率问题目前基本不用)。

    ArrayList,动态数组,内部包含了一个数组,在此基础之上根据继承关系,封装了一组方法,常用的方法如下:

    • ArrayList()
    • ArrayList(int initialCapacity)
    • ArrayList(Collection<? extends E> c)
    • boolean add(E e)
    • public Iterator<E> iterator()

    ArrayList()

    1     /**
    2      * 构造一个空的ArrayList,初始容量为10.
    3      */
    4 
    5     private static final int DEFAULT_CAPACITY = 10;
    6 
    7     public ArrayList() {
    8         this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    9     }

    ArrayList(int initialCapacity) 

     1     /**
     2      * 以指定的容量创建一个ArrayList,其中每一个元素均为空
     3      *
     4      */
     5     public ArrayList(int initialCapacity) {
     6         if (initialCapacity > 0) {
     7             this.elementData = new Object[initialCapacity];
     8         } else if (initialCapacity == 0) {
     9             this.elementData = EMPTY_ELEMENTDATA;
    10         } else {
    11             throw new IllegalArgumentException("Illegal Capacity: "+
    12                                                initialCapacity);
    13         }
    14     }

    ArrayList(Collection<? extends E> c)

     1     /**
     2      * 以现有的集合作为初始值,创建一个新的ArrayList,
     3      * 新的ArrayList为原集合的一个副本。
     4      *
     5      * @param c the collection whose elements are to be placed into this list
     6      * @throws NullPointerException if the specified collection is null
     7      */
     8     public ArrayList(Collection<? extends E> c) {
     9         elementData = c.toArray();
    10         if ((size = elementData.length) != 0) {
    11             // c.toArray might (incorrectly) not return Object[] (see 6260652)
    12             if (elementData.getClass() != Object[].class)
    13                 elementData = Arrays.copyOf(elementData, size, Object[].class);
    14         } else {
    15             // replace with empty array.
    16             this.elementData = EMPTY_ELEMENTDATA;
    17         }
    18     }    

    boolean add(E e)

    ArrayList添加新元素,需要计算添加一个新元素后,当前ArrayList的容量是否足够。如果容量不够,需要将当前容量扩充至当前容量的1.5倍,如果超过虚拟机的最大限制,则截断详细如下:

     1 /**
     2      * Appends the specified element to the end of this list.
     3      *
     4      * @param e element to be appended to this list
     5      * @return <tt>true</tt> (as specified by {@link Collection#add})
     6      */
     7     public boolean add(E e) {
     8         ensureCapacityInternal(size + 1);  // Increments modCount!!
     9         elementData[size++] = e;
    10         return true;
    11     }
    12 
    13     private void ensureCapacityInternal(int minCapacity) {
    14         ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    15     }
    16 
    17     private void ensureExplicitCapacity(int minCapacity) {
    18         modCount++;
    19 
    20         // overflow-conscious code
    21         if (minCapacity - elementData.length > 0)
    22             grow(minCapacity);
    23     }
    24 
    25     /**
    26      * Increases the capacity to ensure that it can hold at least the
    27      * number of elements specified by the minimum capacity argument.
    28      *
    29      * @param minCapacity the desired minimum capacity
    30      */
    31     private void grow(int minCapacity) {
    32         // overflow-conscious code
    33         int oldCapacity = elementData.length;
    34         //容量扩充至当前的1.5倍,如果依然容纳不下实际元素数量,则将实际元素数量作为新的数组的容量,如果
    35         int newCapacity = oldCapacity + (oldCapacity >> 1);
    36         if (newCapacity - minCapacity < 0)
    37             newCapacity = minCapacity;
    38         if (newCapacity - MAX_ARRAY_SIZE > 0)
    39             newCapacity = hugeCapacity(minCapacity);
    40         // 创建新数组的拷贝
    41         elementData = Arrays.copyOf(elementData, newCapacity);
    42     }
    43 
    44 add(E e)

    public Iterator<E> iterator():返回一个Iterator类型的内部类对象,该对象包含了可以操作ArrayList对象的一些Iterator方法,入next、hasNext等方法

     1     public Iterator<E> iterator() {
     2         return new Itr();
     3     }
     4 
     5     /**
     6      * Returns an iterator over the elements in this list in proper sequence.
     7      *
     8      * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
     9      *
    10      * @return an iterator over the elements in this list in proper sequence
    11      */
    12     public Iterator<E> iterator() {
    13         return new Itr(); //创建一个新的内部类对象,该对象包含了对ArrayList对象的常用操作方法,next()、hasNext()、remove()等方法
    14     }
    15 
    16     /**
    17      * An optimized version of AbstractList.Itr
    18      */
    19     private class Itr implements Iterator<E> {
    20         int cursor;       // 当前被操作的元素,默认为0
    21         int lastRet = -1; // 上一个被操作的元素,如果没有则为-1(初始时或上一个元素被删除时,则为0)
    22         int expectedModCount = modCount;
    23 
    24         public boolean hasNext() {
    25             return cursor != size;
    26         }
    27 
    28         @SuppressWarnings("unchecked")
    29         public E next() {
    30             checkForComodification();
    31             int i = cursor;
    32             if (i >= size)
    33                 throw new NoSuchElementException();
    34             Object[] elementData = ArrayList.this.elementData;
    35             if (i >= elementData.length)
    36                 throw new ConcurrentModificationException();
    37             cursor = i + 1;
    38             return (E) elementData[lastRet = i];
    39         }
    40 
    41         public void remove() {
    42             if (lastRet < 0)
    43                 throw new IllegalStateException();
    44             checkForComodification();
    45 
    46             try {
    47                 ArrayList.this.remove(lastRet);
    48                 cursor = lastRet;
    49                 lastRet = -1;
    50                 expectedModCount = modCount;
    51             } catch (IndexOutOfBoundsException ex) {
    52                 throw new ConcurrentModificationException();
    53             }
    54         }
    55     }

    以上是ArrayList中常用且典型的方法源码,理解上面的源码有助于帮助我们理解ArrayList的工作原理和特点。ArrayList在集合中是比较简单,但是非常常用的数据结构,了解了ArrayList可以让我们在合适的场景去使用它。

  • 相关阅读:
    比较对象的相对性
    深拷贝与浅拷贝(TBD)
    创建UI的线程才能访问UI,那么怎样才算访问UI呢
    多层级的数据绑定效果
    众所周知,static修饰的成员只实例化一次,而string类型每次赋值都会重新创建一个实例,那么用static修饰string呢?
    常量、只读字段
    使用dos打开相关软件
    查看电脑硬件信息dos命令
    Windows常用快捷键
    使用外部编辑器出现乱码
  • 原文地址:https://www.cnblogs.com/qq455988971/p/7987945.html
Copyright © 2020-2023  润新知