zoukankan      html  css  js  c++  java
  • java基础,集合,Arraylist,源码解析

    ArrayList

    • 是什么,定义?

    这是动态的数组,它提供了动态的增加和减少元素,实现了List接口(List实现Collection,所以也实现Collection接口)灵活的设置数组的大小等好处

      

    • 内部如何实现
     1     /**
     2      * The array buffer into which the elements of the ArrayList are stored.
     3      * The capacity of the ArrayList is the length of this array buffer.
     4      */
     5     private transient Object[] elementData;//内部是数组
     6 
     7     /**
     8      * The size of the ArrayList (the number of elements it contains).
     9      *
    10      * @serial
    11      */
    12     private int size;//定义大小
    13 
    14     /**
    15      * Constructs an empty list with the specified initial capacity.
    16      *
    17      * @param  initialCapacity  the initial capacity of the list
    18      * @throws IllegalArgumentException if the specified initial capacity
    19      *         is negative
    20      */
    21     public ArrayList(int initialCapacity) {//带参数的初始化
    22         super();
    23         if (initialCapacity < 0)
    24             throw new IllegalArgumentException("Illegal Capacity: "+
    25                                                initialCapacity);
    26         this.elementData = new Object[initialCapacity];
    27     }
    28 
    29     /**
    30      * Constructs an empty list with an initial capacity of ten.
    31      */
    32     public ArrayList() {//默认初始化,大小是10
    33         this(10);
    34     }
    • 添加如何操作
     1   public boolean add(E e) {
     2         ensureCapacityInternal(size + 1);  // 进行长度的判断与修改(将检查与扩容放在一个方法调用,代码阅读性高)
     3         elementData[size++] = e;
     4         return true;
     5     }
     6   
     7     private void ensureCapacityInternal(int minCapacity) {
     8         modCount++;
     9         // overflow-conscious code
    10         if (minCapacity - elementData.length > 0)//进行判断
    11             grow(minCapacity);
    12     }
    13 
    14     private void grow(int minCapacity) {
    15         // overflow-conscious code
    16         int oldCapacity = elementData.length;
    17         int newCapacity = oldCapacity + (oldCapacity >> 1);//扩大原来的二分之一
    18         if (newCapacity - minCapacity < 0)//最小的长度
    19             newCapacity = minCapacity;
    20         if (newCapacity - MAX_ARRAY_SIZE > 0)//最大长度
    21             newCapacity = hugeCapacity(minCapacity);
    22         // minCapacity is usually close to size, so this is a win:
    23         elementData = Arrays.copyOf(elementData, newCapacity);
    24     }
    • 添加重要的一部,扩容,——这是为什么实际应用中要定义数组大小的原因,
     1    //Array的源代码
     2 public static <T> T[] copyOf(T[] original, int newLength) {
     3         return (T[]) copyOf(original, newLength, original.getClass());
     4     }
     5 
     6     public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {//需要复制原来的数组
     7         T[] copy = ((Object)newType == (Object)Object[].class)
     8             ? (T[]) new Object[newLength]
     9             : (T[]) Array.newInstance(newType.getComponentType(), newLength);
    10         System.arraycopy(original, 0, copy, 0,
    11                          Math.min(original.length, newLength));
    12         return copy;
    13     }
    • 制定位置的添加
    1     public void add(int index, E element) {
    2         rangeCheckForAdd(index);
    3 
    4         ensureCapacityInternal(size + 1);  // Increments modCount!!
    5         System.arraycopy(elementData, index, elementData, index + 1,
    6                          size - index);//仅仅是当前位置以后的对象进行复制
    7         elementData[index] = element;
    8         size++;
    9     }
    • 删除对象
        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; // Let gc do its work
    
            return oldValue;
        }
    • 怎么遍历呢?

    数组,通过数组的脚标,遍历;

    for each 因为实现Iterator,也可以使用迭代器

      

    使用中改注意:

    1、初始化最好定义都用的长度,避免Arrarlist内部复制的操作;

    2、如果删除的,尽量从后往前删除

    3、不是线程安全,全部代码中都没有synchronized ,

      如果有需要,使用Vector,两者的区别3点(其他基本是一样):

      线程安全,

      多了方法indexOf,

      扩容的打大小是:1倍

          int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
          capacityIncrement : oldCapacity);

      

  • 相关阅读:
    约瑟夫解决问题的循环链表
    [Erlang危机](5.1.0)VM检测概述
    找呀志_java网络编程(5)TCP和udp差额
    有序输出两棵二叉查找树中的元素
    1234567选择3个数字组合
    八皇后问题
    矩阵乘法运算
    求π的近似值
    证明不小于6的偶数都是两个素数之和
    最大公约数最小公倍数
  • 原文地址:https://www.cnblogs.com/xiebq/p/8325975.html
Copyright © 2011-2022 走看看