日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ArrayList源码

發(fā)布時間:2024/10/14 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ArrayList源码 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1.概覽

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable

實現(xiàn)了 RandomAccess 接口,因此支持隨機訪問。這是理所當(dāng)然的,因為ArrayList 是基于數(shù)組實現(xiàn)的。

數(shù)組的默認(rèn)大小為 10。

private static final int DEFAULT_CAPACITY = 10;

2.序列化

ArrayList基于數(shù)組實現(xiàn),并且具有動態(tài)擴容特性,因此保存元素的數(shù)組不一定都會被使用,那么就沒必要全部進行序列化。

保存元素的數(shù)組elementData使用transient修飾,該關(guān)鍵字聲明數(shù)組默認(rèn)不會被序列化。

transient Object[] elementData; // non-private to simplify nested class access

ArrayList 實現(xiàn)了writeObject() 和 readObject() 來控制只序列化數(shù)組中有元素填充那部分內(nèi)容。

private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {elementData = EMPTY_ELEMENTDATA;// Read in size, and any hidden stuffs.defaultReadObject();// Read in capacitys.readInt(); // ignoredif (size > 0) {// be like clone(), allocate array based upon size not capacityensureCapacityInternal(size);Object[] a = elementData;// Read in all elements in the proper order.for (int i=0; i<size; i++) {a[i] = s.readObject();}} } private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{// Write out element count, and any hidden stuffint expectedModCount = modCount;s.defaultWriteObject();// Write out size as capacity for behavioural compatibility with clone()s.writeInt(size);// Write out all elements in the proper order.for (int i=0; i<size; i++) {s.writeObject(elementData[i]);} if (modCount != expectedModCount) {throw new ConcurrentModificationException();} }

序列化時需要使用 ObjectOutputStreamwriteObject() 將對象轉(zhuǎn)換為字節(jié)流并輸出。

而 writeObject() 方法在傳入的對象存在 writeObject() 的時候會去反射調(diào)用該對象的 writeObject() 來實現(xiàn)序列化。

反序列化使用的是 ObjectInputStream readObject() 方法,原理類似。

ArrayList list = new ArrayList(); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file)); oos.writeObject(list);

3.擴容

添加元素時使用 ensureCapacityInternal() 方法來保證容量足夠,如果不夠時,需要使用 grow() 方法進行擴容,新容量的大小為 oldCapacity + (oldCapacity>> 1) ,也就是舊容量的 1.5 倍。

擴容操作需要調(diào)用 Arrays.copyOf() 把原數(shù)組整個復(fù)制到新數(shù)組中,這個操作代價很高,因此最好在創(chuàng)建 ArrayList 對象時就指定大概的容量大小,減少擴容操作的次數(shù)。

public boolean add(E e) {ensureCapacityInternal(size + 1); // Increments modCount!!elementData[size++] = e;return true; } private void ensureCapacityInternal(int minCapacity) {if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);} ensureExplicitCapacity(minCapacity); } private void ensureExplicitCapacity(int minCapacity) {modCount++;// overflow-conscious codeif (minCapacity - elementData.length > 0)grow(minCapacity); } private void grow(int minCapacity) {// overflow-conscious codeint 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); }

4.刪除元素

需要調(diào)用 System.arraycopy() 將 index+1 后面的元素都復(fù)制到 index 位置上,該操作的時間復(fù)雜度為 O(N),可以看出 ArrayList 刪除元素的代價是非常高的。

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 workreturn oldValue; }

5. Fail-Fast

modCount 用來記錄 ArrayList 結(jié)構(gòu)發(fā)生變化的次數(shù)。

  • 結(jié)構(gòu)發(fā)生變化是指添加或者刪除至少一個元素的所有操作,或者是調(diào)整內(nèi)部數(shù)組的大小,僅僅只是設(shè)置元素的值不算結(jié)構(gòu)發(fā)生變化。

在進行序列化或者迭代等操作時,需要比較操作前后 modCount 是否改變,如果改變了需要拋出 ConcurrentModificationException

private void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException{// Write out element count, and any hidden stuffint expectedModCount = modCount;s.defaultWriteObject();// Write out size as capacity for behavioural compatibilitywith clone()s.writeInt(size);// Write out all elements in the proper order.for (int i=0; i<size; i++) {s.writeObject(elementData[i]);} if (modCount != expectedModCount) {throw new ConcurrentModificationException();} }

?

與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的ArrayList源码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。