国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

從源碼看Java集合之ArrayList

seasonley / 2560人閱讀

摘要:集合之吃透增刪查改從源碼看初始化以及增刪查改,學習。一初始化無參的構造器可以看到這個構造器初始化了一個空數組。指定長度的構造器這個構造器顯式的指明了數組的長度,其實如果小于的話,在添加第一個元素的時候還是會擴充到長度為的數組。

Java集合之ArrayList - 吃透增刪查改

從源碼看初始化以及增刪查改,學習ArrayList。

先來看下ArrayList定義的幾個屬性:

private static final int DEFAULT_CAPACITY = 10;
private static final Object[] EMPTY_ELEMENTDATA = {};
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
transient Object[] elementData;  // 保存對象
private int size; // ArrayList的長度

從這里可以看到ArrayList內部使用數組實現的。

一. 初始化

1. ArrayList()

無參的構造器:

    /**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

可以看到這個構造器初始化了一個空數組。這里有個疑問,就是注釋明明說是構造了一個長度為10的數組,其實這是在添加第一個元素的時候才進行的擴充。

2. ArrayList(int initialCapacity)

指定長度的構造器:

    /**
     * Constructs an empty list with the specified initial capacity.
     *
     * @param  initialCapacity  the initial capacity of the list
     * @throws IllegalArgumentException if the specified initial capacity
     *         is negative
     */
    public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }

這個構造器顯式的指明了數組的長度,其實如果小于10的話,在添加第一個元素的時候還是會擴充到長度為10的數組。

二. 增加元素

1. add(E e)

    /**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return true (as specified by {@link Collection#add})
     * 添加指定的元素到List的末尾
     */
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // 擴充數組長度
        elementData[size++] = e;           // 最后一個賦值為e
        return true;
    }

那么它是如何擴充數組長度的呢?追蹤代碼來到grow(int minCapacity)方法:

/*
* 可以看到它是通過Arrays.copyOf方法將原數組拷貝到了一個數組長度為newCapacity的新數組里面
*/
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);
    }

2. add(int index, E element)

    /**
     * 在指定的位置添加一個元素
     */
    public void add(int index, E element) {
        rangeCheckForAdd(index); // 檢查index是否合法

        ensureCapacityInternal(size + 1);  // 擴充數組長度
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);  // 通過拷貝返回一個新數組
        elementData[index] = element;
        size++;
    }

這里用到了System類的arraycopy方法,它的用法如下:

System. arraycopy(Object src, int srcPos, Object dest, int destPos,int length)

src:原數組;

srcPos:源數組要復制的起始位置;

dest:目標數組;

destPos:目標數組放置的起始位置;

length:復制的長度

這個方法也可以實現自身的復制。上面的就是利用了自身賦值的特性進行數組的拷貝。相當于將index后面的所有元素后移了一位,將新元素插入到index位置。

三. 刪除元素

1. remove(int index)

     /*
     * 和add(int index, E element)類似,使用System.arraycopy進行自身拷貝,相當于將index后面的元素
     * 像前移動了一位,覆蓋掉需要刪除的元素,將最后一個元素置位null,等待JVM自動回收
     */
    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;
    }

2. remove(Object o)

    /*
    * 先通過for循環找到o所在的位置,再通過fastRemove(index)移除,實現方法和remove(int index)一樣
    */
    public boolean remove(Object o) {
        if (o == null) {
            for (int index = 0; index < size; index++)
                if (elementData[index] == null) {
                    fastRemove(index);
                    return true;
                }
        } else {
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index])) {
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }
四. 查找元素
    /*
    * 查找元素就比較簡單了,直接通過數組的下角標進行返回
    */
    public E get(int index) {
        rangeCheck(index);

        return elementData(index);
    }
五. 修改元素
    /*
    * 修改元素也比較簡單,直接通過數組的下角標進行賦值
    */
    public E set(int index, E element) {
        rangeCheck(index);

        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }
總結

從源碼可以看到,ArrayList以數組方式實現,查找和修改的性能比較好,增加和刪除的性能就比較差了。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/68944.html

相關文章

  • java源碼

    摘要:集合源碼解析回歸基礎,集合源碼解析系列,持續更新和源碼分析與是兩個常用的操作字符串的類。這里我們從源碼看下不同狀態都是怎么處理的。 Java 集合深入理解:ArrayList 回歸基礎,Java 集合深入理解系列,持續更新~ JVM 源碼分析之 System.currentTimeMillis 及 nanoTime 原理詳解 JVM 源碼分析之 System.currentTimeMi...

    Freeman 評論0 收藏0
  • Java集合ArrayList源碼解析

    摘要:數組的大小會根據容量的增長而動態的增長,具體的增長方式請看這里構造函數提供了三種方式的構造器。這些元素按照該的迭代器返回的順序排列的。 原文地址 ArrayList ArrayList是List接口的 可變數組的實現。實現了所有可選列表操作,并允許包括 null 在內的所有元素。除了實現 List接口外,此類還提供一些方法來操作內部用來存儲列表的數組的大小。ArrayList繼承自 A...

    W4n9Hu1 評論0 收藏0
  • Week 2 - Java 容器 - 詳細剖析 List ArrayList, Vector,

    摘要:底層使用的是雙向鏈表數據結構之前為循環鏈表,取消了循環。快速隨機訪問就是通過元素的序號快速獲取元素對象對應于方法。而接口就是用來標識該類支持快速隨機訪問。僅僅是起標識作用。,中文名為雙端隊列。不同的是,是線程安全的,內部使用了進行同步。 前言 學習情況記錄 時間:week 2 SMART子目標 :Java 容器 記錄在學習Java容器 知識點中,關于List的需要重點記錄的知識點。...

    MartinDai 評論0 收藏0
  • JDK源碼那些事兒常用的ArrayList

    摘要:前面已經講解集合中的并且也對其中使用的紅黑樹結構做了對應的說明,這次就來看下簡單一些的另一個集合類,也是日常經常使用到的,整體來說,算是比較好理解的集合了,一起來看下前言版本類定義繼承了,實現了,提供對數組隊列的增刪改查操作實現接口,提供隨 前面已經講解集合中的HashMap并且也對其中使用的紅黑樹結構做了對應的說明,這次就來看下簡單一些的另一個集合類,也是日常經常使用到的ArrayL...

    hizengzeng 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<