亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

JDK源碼閱讀——ArrayList

2019-11-11 04:55:57
字體:
來源:轉載
供稿:網友

如同C語言中字符數組向String過渡一樣,作為面向對象語言,自然而然的出現了由Object[]數據形成的集合。本文從JDK源碼出發簡單探討一下ArrayList的幾個重要方法。

Fields

//序列化Id保證了集合是可以進行RPC通信的 PRivate static final long serialVersionUID = 8683452581122892189L; //作為一個普通Object[]數組,集合的默認長度是10 private static final int DEFAULT_CAPACITY = 10; //這里聲明一個空Object數組,用來標示空集合 private static final Object[] EMPTY_ELEMENTDATA = {}; //默認長度的Object數組 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; //真正存儲數據的的Object數組,transient保證不會參與序列化 transient Object[] elementData; //當前ArrayList的長度 private int size;

構造器

//當用戶指定了容量的時候,elementData就是新new出來的Object數組,如果長度指定為0則等于聲明的空Object數組。不支持負數長度。 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的空Object數組。 public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } //如果傳入的是集合類,則拷貝出一個新的Object數組存放用戶輸入的數組內容 public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); if ((size = elementData.length) != 0) { // c.toArray might (incorrectly) not return Object[] (see 6260652) //根據c的聲明方式不同,c.toArray()得到的結果類型是不同的。雖然elementData聲明的是Object數組,但是如果c.toArray()不是Object數組類型,elementData無法存放Object類型。所以這里做了判斷,如果是這種情況,重新拷貝一份新的Object數組。 //關于這點特性可以參考http://blog.csdn.net/aitangyong/article/details/30274749?utm_source=tuicool&utm_medium=referral if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } else { // 如果傳入的長度為0,則elementData等于聲明的空數組 this.elementData = EMPTY_ELEMENTDATA; } }

內部方法

//由于elementData會進行擴容,擴容機制見下文。所以會生成一些沒有用的位置,通過trimToSize方法啊重新生成一段實際長度的Object數組。長度全為有效長度。 public void trimToSize() { modCount++; if (size < elementData.length) { elementData = (size == 0) ? EMPTY_ELEMENTDATA : Arrays.copyOf(elementData, size); } } //核心功能,提前擴容。當需要擴容的空間很大的時候,可以通過這個以前一次性擴容,否則會一次次慢慢擴容。這種方式效率很高。 private void ensureExplicitCapacity(int minCapacity) { modCount++; // 如果用戶希望的大小大于當前的容量,則進行擴容 if (minCapacity - elementData.length > 0) grow(minCapacity); } //擴容方法 private void grow(int minCapacity) { // 新容量為老容量的1.5倍 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); } //最大程度擴容方法 private static int hugeCapacity(int minCapacity) { //如果用戶期待的容量很大,比最大整數還大就是負數了,則OOM if (minCapacity < 0) // overflow throw new OutOfMemoryError(); //否則就給最大的空間 return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; } //新增元素 public void add(int index, E element) { //檢查索引,不合法就異常 rangeCheckForAdd(index); //進行擴容,首先進行+1擴容 ensureCapacityInternal(size + 1); //將index后面的統一往后移動,所以add效率很低 System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; } //刪除元素 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); //把最后一個空出來的賦值null,方便gc回收 elementData[--size] = null; // clear to let GC do its work return oldValue; }//取子列表方法public List<E> subList(int fromIndex, int toIndex) { subListRangeCheck(fromIndex, toIndex, size); return new SubList(this, 0, fromIndex, toIndex); } //檢查參數 static void subListRangeCheck(int fromIndex, int toIndex, int size) { if (fromIndex < 0) throw new IndexOutOfBoundsException("fromIndex = " + fromIndex); if (toIndex > size) throw new IndexOutOfBoundsException("toIndex = " + toIndex); if (fromIndex > toIndex) throw new IllegalArgumentException("fromIndex(" + fromIndex +") > toIndex(" + toIndex + ")"); } private class SubList extends AbstractList<E> implements Randomaccess { private final AbstractList<E> parent; private final int parentOffset; private final int offset; int size; //依然是原始數組,不過是聲明了一個不同的其實與結尾坐標,總體邏輯和外部類ArrayList基本相同 SubList(AbstractList<E> parent, int offset, int fromIndex, int toIndex) { this.parent = parent; this.parentOffset = fromIndex; this.offset = offset + fromIndex; this.size = toIndex - fromIndex; this.modCount = ArrayList.this.modCount; } //jdk1.7以后List本身有了sort功能,不用再通過Collections.sort來排序了 @Override @SuppressWarnings("unchecked") public void sort(Comparator<? super E> c) { final int expectedModCount = modCount; Arrays.sort((E[]) elementData, 0, size, c); if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } modCount++; }

總結

ArrayList的源碼重點在于: 1. 擴容的時候按照原容量的1.5倍擴容 2. 若需要的容量很大,可以通過ensureCapacity進行提前一步到位擴容,或者直接通過構造器聲明一個大的ArrayList。 3. 對Object[]進行操作的時候都是通過System.arraycopy進行的,這是一個native方法,直接操作內存,等同于C語言中的底層方法。 4. 關于默認長度為什么是10,還不是很明白。按照StackOverFlow的說法是作為一個List長度沒有必要是2的次冪。10不大不小,剛好夠用(通過數據分析得到)。但是我仍然不理解為什么HashMap就要是2的次冪。等看完HashMap再來回答這個問題。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品久久久久久久久中文字幕| 亚洲国产又黄又爽女人高潮的| 亚洲女人天堂成人av在线| 91在线|亚洲| 亚洲欧美成人一区二区在线电影| 伊人久久大香线蕉av一区二区| 精品福利在线看| 欧美性猛交xxxx富婆| 91av在线网站| 欧美有码在线观看视频| 日韩精品在线免费| 欧美一区二粉嫩精品国产一线天| 国产精品免费网站| 国产一区二区av| 国产精品99久久久久久久久| 久久精品亚洲热| 欧美日韩在线视频观看| 久久综合伊人77777| 国产精品视频自拍| 国产精品久久久久久久久| 2019中文字幕免费视频| 日韩欧美国产视频| 78色国产精品| 69久久夜色精品国产69| 91免费高清视频| 午夜精品久久久久久久白皮肤| 国产丝袜一区二区三区| 亚洲人成电影网站色xx| 成人黄色在线免费| 欧美精品中文字幕一区| 精品亚洲一区二区三区在线播放| 久久久久久尹人网香蕉| 2019中文字幕免费视频| 亚洲片国产一区一级在线观看| 久久99久久99精品免观看粉嫩| 欧美一级在线亚洲天堂| 91久久在线视频| 日本aⅴ大伊香蕉精品视频| 国产一区二区三区毛片| 91人成网站www| 大胆人体色综合| 国产精品美女在线| 亚洲第一二三四五区| 伊人久久久久久久久久| 高清欧美性猛交| 欧美日韩国产丝袜另类| 88xx成人精品| 欧美日韩免费网站| 国产精品自拍网| 欧美日韩中文字幕日韩欧美| 亚洲国产精品资源| 亚洲一区二区三区香蕉| 欧日韩在线观看| 日韩男女性生活视频| 91精品久久久久久久久久| 日韩欧美国产高清91| 欧美激情视频网址| 亚洲最大成人免费视频| 色婷婷亚洲mv天堂mv在影片| 久久久久久久色| 欧美激情一二三| 久久久久久国产精品| 国产精品成人va在线观看| 亚洲天堂免费观看| 亚洲午夜激情免费视频| 国产成人精品a视频一区www| 91精品视频在线播放| 欧美三级xxx| 欧美精品久久久久| 色悠悠国产精品| 国产精品久久久久久五月尺| 久久这里有精品| 欧美一级大片在线观看| 亚洲成人在线网| 欧美激情在线一区| 亚洲综合小说区| 亚洲欧洲在线播放| 国产日韩中文字幕在线| 欧美日韩国产成人在线| 国内精品伊人久久| 亚洲国产黄色片| 大伊人狠狠躁夜夜躁av一区| 日韩经典一区二区三区| 欧美亚洲成人网| 欧美性精品220| 91精品啪aⅴ在线观看国产| 韩国精品美女www爽爽爽视频| 亚洲精品黄网在线观看| 欧美日韩人人澡狠狠躁视频| 中文字幕精品www乱入免费视频| www.99久久热国产日韩欧美.com| 久久久久久免费精品| 亚洲精品wwwww| 国产欧美va欧美va香蕉在| 国产精品免费久久久久久| 亚洲大胆人体av| 日韩欧美有码在线| 在线视频国产日韩| 亚洲精品国精品久久99热一| 日本高清不卡的在线| 日本久久91av| 亚洲男人天堂2024| 国产一区二区激情| 久久夜色精品国产亚洲aⅴ| 亚洲欧美999| 久久中文精品视频| 在线观看国产欧美| 久久91亚洲精品中文字幕奶水| 91亚洲午夜在线| 亚洲综合色激情五月| 日韩高清中文字幕| 国产亚洲一区二区精品| 亚洲美女又黄又爽在线观看| 亚洲高清福利视频| 亚洲国产第一页| 国产精品视频成人| 欧美大奶子在线| 欧美激情第6页| 国产精品自拍视频| 国产精品va在线播放我和闺蜜| 亚洲专区在线视频| 日韩欧美在线观看| 国产精品高潮呻吟久久av野狼| 成人97在线观看视频| 国产精品第一视频| 97香蕉超级碰碰久久免费软件| 日韩精品免费一线在线观看| 日产日韩在线亚洲欧美| 成人网在线免费看| 亚洲欧美在线看| 国产欧美va欧美va香蕉在| 性欧美长视频免费观看不卡| 中文字幕免费精品一区高清| 国产一区红桃视频| 日本国产高清不卡| 91中文在线视频| 欧美日韩国产综合视频在线观看中文| 精品国产欧美一区二区五十路| 亚洲图片在区色| 欧美高清性猛交| 亚洲国产欧美一区二区三区久久| 欧美午夜www高清视频| 热久久这里只有精品| 成人激情黄色网| 久久精品人人爽| 欧美乱妇40p| 麻豆国产精品va在线观看不卡| 国产999精品视频| 亚洲www永久成人夜色| 久久久免费在线观看| 国产精品日韩欧美综合| 7m第一福利500精品视频| 久久精品99久久香蕉国产色戒| 亚洲永久免费观看| 亚洲国产日韩精品在线| 久久精品视频亚洲| 亚洲aaa激情| 亚洲最新视频在线| 国产欧美精品xxxx另类| 在线精品播放av| 国产精品黄视频| 久久综合电影一区| 日本中文字幕久久看| 国产欧美 在线欧美|