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

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

JDK源碼閱讀——ArrayList

2019-11-11 05:42:56
字體:
來源:轉載
供稿:網友

如同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在线精品| 麻豆国产精品va在线观看不卡| 国产精品91久久久久久| 欧美www视频在线观看| 亚洲美女黄色片| 92国产精品视频| 91精品久久久久久久久久久| 国产精品91久久久久久| 亚洲欧洲在线观看| 国产精品永久免费在线| 亚洲二区中文字幕| 最近的2019中文字幕免费一页| 久久精品成人欧美大片古装| 亚洲另类图片色| 成人中文字幕+乱码+中文字幕| 亚洲视频一区二区| 日韩国产欧美区| 成人淫片在线看| 欧美高清在线视频观看不卡| 亚洲男人天堂九九视频| 亚洲自拍偷拍网址| 久久精品99久久久久久久久| 久久国产精品亚洲| 热久久免费视频精品| 欧美精品久久久久久久久久| 亚洲一区二区三区乱码aⅴ| 欧美国产极速在线| 欧美成人免费网| 国产精品电影网| 亚洲国产成人久久综合一区| 亚洲精品久久久久中文字幕二区| 热99精品里视频精品| 韩国19禁主播vip福利视频| 欧美激情在线观看| 91在线观看免费高清完整版在线观看| 日韩av在线免费播放| 成人免费视频网址| 97涩涩爰在线观看亚洲| 亚洲福利视频免费观看| 国产在线高清精品| 久久久久久国产精品三级玉女聊斋| 亚洲国产精品久久久久秋霞不卡| 国产亚洲综合久久| 91亚洲人电影| 国产精品夜间视频香蕉| 久久久久久成人精品| 国产精品视频一区二区三区四| 欧美视频裸体精品| 国产精品亚洲欧美导航| 人人澡人人澡人人看欧美| 国产成人精品一区二区三区| 久久久成人精品| 欧美精品在线免费播放| 亚洲日本欧美日韩高观看| 中国日韩欧美久久久久久久久| 久久99国产精品自在自在app| 国产亚洲精品久久久久久牛牛| 久久精品精品电影网| 中文字幕亚洲一区在线观看| 亚洲小视频在线| 久久影视电视剧凤归四时歌| 亚洲国产精彩中文乱码av在线播放| 亚洲第一区第一页| 亚洲社区在线观看| 欧美大荫蒂xxx| 97成人精品区在线播放| 欧美一区二区.| 国产亚洲精品久久久久久777| 91久久精品美女| 亚洲自拍av在线| 亚洲欧美激情另类校园| 久久影视电视剧免费网站清宫辞电视| 中文国产成人精品久久一| 久久久久久久久亚洲| 欧美成年人视频网站欧美| 日韩av在线一区| 91久久久久久久久久久久久| 国产黑人绿帽在线第一区| 日韩国产在线播放| 97久久精品视频| 欧美精品久久久久久久免费观看| 欧美最猛性xxxxx(亚洲精品)| 久久久视频免费观看| 成人精品视频99在线观看免费| 国产69久久精品成人看| 日韩在线观看电影| 久久久久国产精品一区| 欧美极品在线视频| 国产精品 欧美在线| 亚洲网站在线看| 2024亚洲男人天堂| 欧美激情国产精品| 奇米四色中文综合久久| 91精品久久久久久久久不口人| 精品偷拍各种wc美女嘘嘘| 亚洲精品日韩在线| 成人黄色在线播放| 亚洲人成电影在线观看天堂色| 欧美在线观看网站| 亚洲一级黄色片| 久久人体大胆视频| 国产精品美乳一区二区免费| 久久色精品视频| 亚洲free嫩bbb| 国内精品久久久久久影视8| 亚洲精品自拍第一页| 成人激情视频网| 国产精品扒开腿做爽爽爽的视频| 青青久久av北条麻妃海外网| 欧美精品999| 8050国产精品久久久久久| 2020欧美日韩在线视频| 国产视频精品一区二区三区| 亚洲xxx自由成熟| 日韩av在线免费| 日韩成人av在线| 日韩中文字幕国产| 国产成人在线一区二区| 亚洲人成绝费网站色www| 亚洲天堂av综合网| 麻豆一区二区在线观看| 久久久国产一区二区| 精品视频偷偷看在线观看| 久久99久久99精品免观看粉嫩| 另类美女黄大片| 国产精品久久久久久久久久ktv| 欧美激情视频一区二区| 亚洲免费成人av电影| 国产精自产拍久久久久久| 色综合色综合网色综合| 亚洲综合中文字幕在线观看| 日韩av影片在线观看| 欧美成人免费观看| 69久久夜色精品国产69| 国产精品视频久久| 亚洲香蕉av在线一区二区三区| 亚洲精品98久久久久久中文字幕| 国产精品色午夜在线观看| 欧美精品免费播放| 日韩在线视频免费观看| 亚洲午夜女主播在线直播| 欧美日韩ab片| 国产suv精品一区二区三区88区| 亚洲精品成人免费| 亚洲电影免费观看| 欧美视频免费在线| 国产精品影片在线观看| 日本中文字幕不卡免费| 日韩av在线网址| 日韩一二三在线视频播| 91人人爽人人爽人人精88v| 91精品国产综合久久久久久蜜臀| 538国产精品一区二区在线| 国产欧美日韩精品在线观看| 亚洲精品mp4| 91色中文字幕| 国产精品一区二区久久国产| 国产在线视频2019最新视频| 91系列在线观看| 精品成人国产在线观看男人呻吟| 亚洲午夜小视频| 91人成网站www| 在线电影av不卡网址|