麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

陌兮大魔王帶你深入 學(xué)習(xí)ArrayListA(一)

2019-11-10 20:00:49
字體:
供稿:網(wǎng)友

前引

ArrayList的重要性就不言而喻了,在此鄙人就不多說了。本文適合新手閱讀,如果是大神來訪,還望能夠幫忙發(fā)現(xiàn)小子知識(shí)不足之處,不甚感激。

ArrayList是什么?

ArrayList是什么?不就是容器嗎,裝個(gè)東西而已!如果你是這樣回答的,那問:它底層到底是什么?你又如何作答?其實(shí)這時(shí)候,我們就因該深入其源碼來學(xué)習(xí)了。一看到源碼啊,許多新手肯定都是拒絕的。不外乎兩種原因:1、代碼看不懂,2、注釋比代碼更看不懂。所以,鄙人希望,我能給大家獻(xiàn)點(diǎn)薄力,為大家的知識(shí)體系添磚蓋瓦。

ArrayList(JDK1.6)源碼:

其實(shí)很多源碼都不難.而ArrayList的源碼同樣如此。現(xiàn)在就讓我們走進(jìn)ArrayList的源碼世界(篇幅有限,挑一些常用的來說):進(jìn)入ArrayList的源碼中,首先看到的是這樣一段代碼
PRivate transient Object[] elementData;
private int size;
protected transient int modCount = 0;(來之父類AbstractList,ArrayList不存在)這個(gè)elementData就是用來存放數(shù)據(jù)的object數(shù)組。size是數(shù)組的大長(zhǎng)度,代表的是ArrayList的所存貯的數(shù)據(jù)的容量。modCount用來記錄容器被改變的次數(shù)(對(duì)理解沒什么用,后文不再解釋這個(gè)變量)。然后我們看到的是ArrayList的構(gòu)造器
    public ArrayList(int initialCapacity) {	super();        if (initialCapacity < 0)            throw new IllegalArgumentException("Illegal Capacity: "+                                               initialCapacity);	this.elementData = new Object[initialCapacity];    }
    public ArrayList() {	this(10);    }這段代碼是初始化ArrayList用的。從中我們可以看出,實(shí)例ArrayList有兩種方法,而我們不一般不帶參數(shù)的時(shí)候,ArrayList默認(rèn)的大小是10.即產(chǎn)生一個(gè)容量為10的elementData的object數(shù)組。下一段代碼
    public void ensureCapacity(int minCapacity) {	modCount++;	int oldCapacity = elementData.length;	if (minCapacity > oldCapacity) {	    Object oldData[] = elementData;	    int newCapacity = (oldCapacity * 3)/2 + 1;    	    if (newCapacity < minCapacity)		newCapacity = minCapacity;            // minCapacity is usually close to size, so this is a win:            elementData = Arrays.copyOf(elementData, newCapacity);	}    }這一段是為了確保數(shù)組可以存放下不停增多的數(shù)據(jù),而專門設(shè)計(jì)的增加數(shù)組的長(zhǎng)度的方法。從中 可以看出實(shí)現(xiàn)思路是:當(dāng)需要存放數(shù)據(jù)到elementData數(shù)組中去的時(shí)候,會(huì)傳入minCapcity(表示該數(shù)組應(yīng)存入的總數(shù)據(jù)量),如果minCapcity大于現(xiàn)在的數(shù)組的長(zhǎng)度,就產(chǎn)生一個(gè)新的數(shù)組,容量為以前的1.5倍+1,如果仍然小于,就直接將容量設(shè)置為minCapcity。然后再將之前存放在原數(shù)組的數(shù)據(jù)復(fù)制到新的數(shù)組中去,就實(shí)現(xiàn)了整個(gè)數(shù)組的擴(kuò)容!看完前置準(zhǔn)備的各種方法之后,可以看操作的方法了:size():
    public int size() {	return size;    }size就是elementData的長(zhǎng)度。
    public boolean isEmpty() {	return size == 0;    }返回size==0的判斷結(jié)果indexOf(Object o):
    public int indexOf(Object o) {	if (o == null) {	    for (int i = 0; i < size; i++)		if (elementData[i]==null)		    return i;	} else {	    for (int i = 0; i < size; i++)		if (o.equals(elementData[i]))		    return i;	}	return -1;    }傳入一個(gè)對(duì)象,返回其索引。 可以看出這個(gè)方法只是將傳入的對(duì)象和elementData中的每個(gè)元素進(jìn)行比較,然后再返回其數(shù)組下標(biāo)號(hào)。找不到的話,就返回-1。contains(Object o)也只是調(diào)用了這個(gè)方法而已。lastIndexOf(Object o):
    public int lastIndexOf(Object o) {	if (o == null) {	    for (int i = size-1; i >= 0; i--)		if (elementData[i]==null)		    return i;	} else {	    for (int i = size-1; i >= 0; i--)		if (o.equals(elementData[i]))		    return i;	}	return -1;    }可以看見lastIndexOf方法和indexOf是如此的相似,只是將遍歷方向改變了一下就又多了一個(gè)方法,哈哈!get(index):
    public E get(int index) {	RangeCheck(index);	return (E) elementData[index];    }
    private void RangeCheck(int index) {	if (index >= size)	    throw new IndexOutOfBoundsException(		"Index: "+index+", Size: "+size);    }set(index,object)
    public E set(int index, E element) {	RangeCheck(index);	E oldValue = (E) elementData[index];	elementData[index] = element;	return oldValue;    }可以發(fā)現(xiàn)很多操作都只是在操作數(shù)組而已!畢竟ArrayList就是數(shù)組。add(o):
    public boolean add(E e) {	ensureCapacity(size + 1);  // Increments modCount!!	elementData[size++] = e;	return true;    }add方法也是如此,只是此處需要判斷是否要擴(kuò)容add(index,object):
    public void add(int index, E element) {	if (index > size || index < 0)	    throw new IndexOutOfBoundsException(		"Index: "+index+", Size: "+size);	ensureCapacity(size+1);  // Increments modCount!!	System.arraycopy(elementData, index, elementData, index + 1,			 size - index);	elementData[index] = element;	size++;    }在某個(gè)位置插入一個(gè)對(duì)象,這段代碼難得也就這就話:System.arraycopy(elementData, index, elementData, index + 1, size - index); 其實(shí)這句好的意思是:將elementData從其第index和后面的元素,復(fù)制到elementData的第index+1和之后的位置,共復(fù)制size-index個(gè)元素,這樣就是實(shí)現(xiàn)了將第index為元素騰空,讓外界傳進(jìn)來的object占據(jù)這個(gè)寶座。這也是前面擴(kuò)容的時(shí)候使用的是size+1而不是size的原因(確保數(shù)組復(fù)制時(shí)弄的size+1不會(huì)越界)remove(index):
    public E remove(int index) {	RangeCheck(index);	modCount++;	E oldValue = (E) elementData[index];	int numMoved = size - index - 1;	if (numMoved > 0)	    System.arraycopy(elementData, index+1, elementData, index,			     numMoved);	elementData[--size] = null; // Let gc do its work	return oldValue;    }可以發(fā)現(xiàn)和add是差不多的,而且還不許要考慮擴(kuò)容的問題。同樣的remove(object)相比起來,就多了一個(gè)判斷該對(duì)象的index在哪,然后直接調(diào)用這個(gè)方法就行了。

總結(jié):

看到這里,想必大家對(duì)ArrayList也算有一個(gè)清晰地認(rèn)知了。同時(shí)也明白了源碼并不是很難,而且觀看源碼可以很好地加深我們對(duì)知識(shí)的理解,理解到底層。這樣的學(xué)習(xí)會(huì)讓我們的知識(shí)變得更加牢靠!由于今天實(shí)在是太晚了,所以沒有貼上自定義實(shí)現(xiàn)的MyArrayList的代碼(還沒有寫哭),所以今天只能告一段落了,若是大家還覺得不過癮,想對(duì)容器有進(jìn)一步的加深的欲望,希望能夠繼續(xù)觀看我的博文。以后的文章我會(huì)逐一地對(duì)LinkedList,Map,Set,Tree等容器進(jìn)行源碼的解析,還希望大家能夠多多支持,謝謝大家!如果有什么問題,還希望能夠一起討論,若是有什么不足之處,請(qǐng)一定要告訴我,謝謝大笑
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 亚洲婷婷日日综合婷婷噜噜噜 | 史上最强炼体老祖动漫在线观看 | 国产成人高潮免费观看精品 | jizzyouxxxx| 最新中文字幕第一页视频 | 精品国产一区二区三区四区阿崩 | 毛片免费在线视频 | 久久久久北条麻妃免费看 | 性欧美日本 | 成人一级免费视频 | chinese 军人 gay xx 呻吟 | 一级免费特黄视频 | 久久精品亚洲精品国产欧美kt∨ | 中国7777高潮网站 | 国产精品美女久久久久久不卡 | 精品国产一区三区| 久久精品视频12 | 性生活视频网站 | 亚洲视频在线视频 | 在线天堂中文在线资源网 | 毛片在线免费播放 | 久久精品黄 | 精品在线视频播放 | 成人在线视频在线观看 | 中国免费一级毛片 | 国产99久久久国产精品 | 一本色道久久久888 香蕉视频99 | 久久久久久久.comav | 欧美一级成人一区二区三区 | 久久国产精品99国产 | 毛片免费在线观看视频 | 久久国产精品小视频 | 国产精品久久久久久久av三级 | av噜噜在线| 亚洲影视在线观看 | 毛片视频网址 | 一区二区三视频 | 欧美级毛片 | 久久久久久久久成人 | 嗯~啊~弄嗯~啊h高潮视频 | 极品一级片 |