摘要:集合之吃透增刪查改從源碼看初始化以及增刪查改,學習。一初始化無參的構(gòu)造器可以看到這個構(gòu)造器初始化了一個空數(shù)組。指定長度的構(gòu)造器這個構(gòu)造器顯式的指明了數(shù)組的長度,其實如果小于的話,在添加第一個元素的時候還是會擴充到長度為的數(shù)組。
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內(nèi)部使用數(shù)組實現(xiàn)的。
一. 初始化1. ArrayList()
無參的構(gòu)造器:
/** * Constructs an empty list with an initial capacity of ten. */ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
可以看到這個構(gòu)造器初始化了一個空數(shù)組。這里有個疑問,就是注釋明明說是構(gòu)造了一個長度為10的數(shù)組,其實這是在添加第一個元素的時候才進行的擴充。
2. ArrayList(int initialCapacity)
指定長度的構(gòu)造器:
/** * 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); } }
這個構(gòu)造器顯式的指明了數(shù)組的長度,其實如果小于10的話,在添加第一個元素的時候還是會擴充到長度為10的數(shù)組。
二. 增加元素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); // 擴充數(shù)組長度 elementData[size++] = e; // 最后一個賦值為e return true; }
那么它是如何擴充數(shù)組長度的呢?追蹤代碼來到grow(int minCapacity)方法:
/* * 可以看到它是通過Arrays.copyOf方法將原數(shù)組拷貝到了一個數(shù)組長度為newCapacity的新數(shù)組里面 */ 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); // 擴充數(shù)組長度 System.arraycopy(elementData, index, elementData, index + 1, size - index); // 通過拷貝返回一個新數(shù)組 elementData[index] = element; size++; }
這里用到了System類的arraycopy方法,它的用法如下:
System. arraycopy(Object src, int srcPos, Object dest, int destPos,int length)
src:原數(shù)組;
srcPos:源數(shù)組要復制的起始位置;
dest:目標數(shù)組;
destPos:目標數(shù)組放置的起始位置;
length:復制的長度
這個方法也可以實現(xiàn)自身的復制。上面的就是利用了自身賦值的特性進行數(shù)組的拷貝。相當于將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循環(huán)找到o所在的位置,再通過fastRemove(index)移除,實現(xiàn)方法和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; }四. 查找元素
/* * 查找元素就比較簡單了,直接通過數(shù)組的下角標進行返回 */ public E get(int index) { rangeCheck(index); return elementData(index); }五. 修改元素
/* * 修改元素也比較簡單,直接通過數(shù)組的下角標進行賦值 */ public E set(int index, E element) { rangeCheck(index); E oldValue = elementData(index); elementData[index] = element; return oldValue; }總結(jié)
從源碼可以看到,ArrayList以數(shù)組方式實現(xiàn),查找和修改的性能比較好,增加和刪除的性能就比較差了。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/68944.html
摘要:數(shù)組的大小會根據(jù)容量的增長而動態(tài)的增長,具體的增長方式請看這里構(gòu)造函數(shù)提供了三種方式的構(gòu)造器。這些元素按照該的迭代器返回的順序排列的。 原文地址 ArrayList ArrayList是List接口的 可變數(shù)組的實現(xiàn)。實現(xiàn)了所有可選列表操作,并允許包括 null 在內(nèi)的所有元素。除了實現(xiàn) List接口外,此類還提供一些方法來操作內(nèi)部用來存儲列表的數(shù)組的大小。ArrayList繼承自 A...
摘要:底層使用的是雙向鏈表數(shù)據(jù)結(jié)構(gòu)之前為循環(huán)鏈表,取消了循環(huán)??焖匐S機訪問就是通過元素的序號快速獲取元素對象對應于方法。而接口就是用來標識該類支持快速隨機訪問。僅僅是起標識作用。,中文名為雙端隊列。不同的是,是線程安全的,內(nèi)部使用了進行同步。 前言 學習情況記錄 時間:week 2 SMART子目標 :Java 容器 記錄在學習Java容器 知識點中,關(guān)于List的需要重點記錄的知識點。...
摘要:前面已經(jīng)講解集合中的并且也對其中使用的紅黑樹結(jié)構(gòu)做了對應的說明,這次就來看下簡單一些的另一個集合類,也是日常經(jīng)常使用到的,整體來說,算是比較好理解的集合了,一起來看下前言版本類定義繼承了,實現(xiàn)了,提供對數(shù)組隊列的增刪改查操作實現(xiàn)接口,提供隨 前面已經(jīng)講解集合中的HashMap并且也對其中使用的紅黑樹結(jié)構(gòu)做了對應的說明,這次就來看下簡單一些的另一個集合類,也是日常經(jīng)常使用到的ArrayL...
閱讀 4760·2021-11-15 11:39
閱讀 2700·2021-11-11 16:55
閱讀 2208·2021-10-25 09:44
閱讀 3512·2021-09-22 16:02
閱讀 2444·2019-08-30 15:55
閱讀 3132·2019-08-30 13:46
閱讀 2674·2019-08-30 13:15
閱讀 1959·2019-08-30 11:12