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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

java源码分析之ArrayList

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

ArrayList就是傳說中的動態(tài)數(shù)組,就是Array的復(fù)雜版本,它提供了如下一些好處:動態(tài)的增加和減少元素、靈活的設(shè)置數(shù)組的大小......

? ??認(rèn)真閱讀本文,我相信一定會對你有幫助。比如為什么ArrayList里面提供了一個受保護(hù)的removeRange方法?提供了其他沒有被調(diào)用過的私有方法?

? ? 首先看到對ArrayList的定義:

[java]?view plaincopy
  • public?class?ArrayList<E>?extends?AbstractList<E>??implements?List<E>,?RandomAccess,?Cloneable,?java.io.Serializable??
  • ?從ArrayList<E>可以看出它是支持泛型的,它繼承自AbstractList,實(shí)現(xiàn)了List、RandomAccess、Cloneable、java.io.Serializable接口。

    ? ??AbstractList提供了List接口的默認(rèn)實(shí)現(xiàn)(個別方法為抽象方法)。

    ? ? List接口定義了列表必須實(shí)現(xiàn)的方法。

    ? ??RandomAccess是一個標(biāo)記接口,接口內(nèi)沒有定義任何內(nèi)容。

    ? ??實(shí)現(xiàn)了Cloneable接口的類,可以調(diào)用Object.clone方法返回該對象的淺拷貝。

    ? ??通過實(shí)現(xiàn) java.io.Serializable 接口以啟用其序列化功能。未實(shí)現(xiàn)此接口的類將無法使其任何狀態(tài)序列化或反序列化。序列化接口沒有方法或字段,僅用于標(biāo)識可序列化的語義。

    ? ??ArrayList的屬性

    ? ??ArrayList定義只定義類兩個私有屬性:

    [java]?view plaincopy
  • /**?
  • ??????*?The?array?buffer?into?which?the?elements?of?the?ArrayList?are?stored.?
  • ??????*?The?capacity?of?the?ArrayList?is?the?length?of?this?array?buffer.?
  • ??????*/??
  • ?????private?transient?Object[]?elementData;??
  • ???
  • ?????/**?
  • ??????*?The?size?of?the?ArrayList?(the?number?of?elements?it?contains).?
  • ??????*?
  • ??????*?@serial?
  • ??????*/??
  • ?????private?int?size;??

  • [java]?view plaincopy
  • 很容易理解,elementData存儲ArrayList內(nèi)的元素,size表示它包含的元素的數(shù)量。??
  • ??
  • ??有個關(guān)鍵字需要解釋:transient。??
  • ??
  • ??Java的serialization提供了一種持久化對象實(shí)例的機(jī)制。當(dāng)持久化對象時,可能有一個特殊的對象數(shù)據(jù)成員,我們不想用serialization機(jī)制來保存它。為了在一個特定對象的一個域上關(guān)閉serialization,可以在這個域前加上關(guān)鍵字transient。??
  • ansient是Java語言的關(guān)鍵字,用來表示一個域不是該對象串行化的一部分。當(dāng)一個對象被串行化的時候,transient型變量的值不包括在串行化的表示中,然而非transient型的變量是被包括進(jìn)去的。??
  • ??
  • ??有點(diǎn)抽象,看個例子應(yīng)該能明白。??

  • [java]?view plaincopy
  • public?class?UserInfo?implements?Serializable?{??
  • ?????private?static?final?long?serialVersionUID?=?996890129747019948L;??
  • ?????private?String?name;??
  • ?????private?transient?String?psw;??
  • ???
  • ?????public?UserInfo(String?name,?String?psw)?{??
  • ?????????this.name?=?name;??
  • ?????????this.psw?=?psw;??
  • ?????}??
  • ???
  • ?????public?String?toString()?{??
  • ?????????return?"name="?+?name?+?",?psw="?+?psw;??
  • ?????}??
  • ?}??
  • ???
  • ?public?class?TestTransient?{??
  • ?????public?static?void?main(String[]?args)?{??
  • ?????????UserInfo?userInfo?=?new?UserInfo("張三",?"123456");??
  • ?????????System.out.println(userInfo);??
  • ?????????try?{??
  • ?????????????//?序列化,被設(shè)置為transient的屬性沒有被序列化??
  • ?????????????ObjectOutputStream?o?=?new?ObjectOutputStream(new?FileOutputStream(??
  • ?????????????????????"UserInfo.out"));??
  • ?????????????o.writeObject(userInfo);??
  • ?????????????o.close();??
  • ?????????}?catch?(Exception?e)?{??
  • ?????????????//?TODO:?handle?exception??
  • ?????????????e.printStackTrace();??
  • ?????????}??
  • ?????????try?{??
  • ?????????????//?重新讀取內(nèi)容??
  • ?????????????ObjectInputStream?in?=?new?ObjectInputStream(new?FileInputStream(??
  • ?????????????????????"UserInfo.out"));??
  • ?????????????UserInfo?readUserInfo?=?(UserInfo)?in.readObject();??
  • ?????????????//讀取后psw的內(nèi)容為null??
  • ?????????????System.out.println(readUserInfo.toString());??
  • ?????????}?catch?(Exception?e)?{??
  • ?????????????//?TODO:?handle?exception??
  • ?????????????e.printStackTrace();??
  • ?????????}??
  • ?????}??
  • ?}??
  • ?被標(biāo)記為transient的屬性在對象被序列化的時候不會被保存。

    ? ? 接著回到ArrayList的分析中......

    ? ??ArrayList的構(gòu)造方法

    ? ? 看完屬性看構(gòu)造方法。ArrayList提供了三個構(gòu)造方法:

    [java]?view plaincopy
  • /**?
  • ??????*?Constructs?an?empty?list?with?the?specified?initial?capacity.?
  • ??????*/??
  • ?????public?ArrayList(int?initialCapacity)?{??
  • ?????super();??
  • ?????????if?(initialCapacity?<?0)??
  • ?????????????throw?new?IllegalArgumentException("Illegal?Capacity:?"+??
  • ????????????????????????????????????????????????initialCapacity);??
  • ?????this.elementData?=?new?Object[initialCapacity];??
  • ?????}??
  • ???
  • ?????/**?
  • ??????*?Constructs?an?empty?list?with?an?initial?capacity?of?ten.?
  • ??????*/??
  • ?????public?ArrayList()?{??
  • ?????this(10);??
  • ?????}??
  • ???
  • ?????/**?
  • ??????*?Constructs?a?list?containing?the?elements?of?the?specified?
  • ??????*?collection,?in?the?order?they?are?returned?by?the?collection's?
  • ??????*?iterator.?
  • ??????*/??
  • ?????public?ArrayList(Collection<??extends?E>?c)?{??
  • ?????elementData?=?c.toArray();??
  • ?????size?=?elementData.length;??
  • ?????//?c.toArray?might?(incorrectly)?not?return?Object[]?(see?6260652)??
  • ?????if?(elementData.getClass()?!=?Object[].class)??
  • ?????????elementData?=?Arrays.copyOf(elementData,?size,?Object[].class);??
  • ?????}??
  • ? ?第一個構(gòu)造方法使用提供的initialCapacity來初始化elementData數(shù)組的大小。第二個構(gòu)造方法調(diào)用第一個構(gòu)造方法并傳入?yún)?shù)10,即默認(rèn)elementData數(shù)組的大小為10。第三個構(gòu)造方法則將提供的集合轉(zhuǎn)成數(shù)組返回給elementData(返回若不是Object[]將調(diào)用Arrays.copyOf方法將其轉(zhuǎn)為Object[])。

    ? ??ArrayList的其他方法

    ? ? add(E e)

    ? ? add(E e)都知道是在尾部添加一個元素,如何實(shí)現(xiàn)的呢?

    [java]?view plaincopy
  • public?boolean?add(E?e)?{??
  • ????ensureCapacity(size?+?1);??//?Increments?modCount!!??
  • ????elementData[size++]?=?e;??
  • ????return?true;??
  • ????}??
  • ?書上都說ArrayList是基于數(shù)組實(shí)現(xiàn)的,屬性中也看到了數(shù)組,具體是怎么實(shí)現(xiàn)的呢?比如就這個添加元素的方法,如果數(shù)組大,則在將某個位置的值設(shè)置為指定元素即可,如果數(shù)組容量不夠了呢?

    ? ? 看到add(E e)中先調(diào)用了ensureCapacity(size+1)方法,之后將元素的索引賦給elementData[size],而后size自增。例如初次添加時,size為0,add將elementData[0]賦值為e,然后size設(shè)置為1(類似執(zhí)行以下兩條語句elementData[0]=e;size=1)。將元素的索引賦給elementData[size]不是會出現(xiàn)數(shù)組越界的情況嗎?這里關(guān)鍵就在ensureCapacity(size+1)中了。

    ? ? 根據(jù)ensureCapacity的方法名可以知道是確保容量用的。ensureCapacity(size+1)后面的注釋可以明白是增加modCount的值(加了倆感嘆號,應(yīng)該蠻重要的,來看看)。

    [java]?view plaincopy
  • /**?
  • ??????*?Increases?the?capacity?of?this?<tt>ArrayList</tt>?instance,?if?
  • ??????*?necessary,?to?ensure?that?it?can?hold?at?least?the?number?of?elements?
  • ??????*?specified?by?the?minimum?capacity?argument.?
  • ??????*?
  • ??????*?@param???minCapacity???the?desired?minimum?capacity?
  • ??????*/??
  • ?????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);??
  • ?????}??
  • ?????}??
  • The number of times this list has been structurally modified.

    ? ? 這是對modCount的解釋,意為記錄list結(jié)構(gòu)被改變的次數(shù)(觀察源碼可以發(fā)現(xiàn)每次調(diào)用ensureCapacoty方法,modCount的值都將增加,但未必?cái)?shù)組結(jié)構(gòu)會改變,所以感覺對modCount的解釋不是很到位)。

    ? ??增加modCount之后,判斷minCapacity(即size+1)是否大于oldCapacity(即elementData.length),若大于,則調(diào)整容量為max((oldCapacity*3)/2+1,minCapacity),調(diào)整elementData容量為新的容量,即將返回一個內(nèi)容為原數(shù)組元素,大小為新容量的數(shù)組賦給elementData;否則不做操作。

    ? ? 所以調(diào)用ensureCapacity至少將elementData的容量增加的1,所以elementData[size]不會出現(xiàn)越界的情況。

    ? ??容量的拓展將導(dǎo)致數(shù)組元素的復(fù)制,多次拓展容量將執(zhí)行多次整個數(shù)組內(nèi)容的復(fù)制。若提前能大致判斷l(xiāng)ist的長度,調(diào)用ensureCapacity調(diào)整容量,將有效的提高運(yùn)行速度。

    ? ? 可以理解提前分配好空間可以提高運(yùn)行速度,但是測試發(fā)現(xiàn)提高的并不是很大,而且若list原本數(shù)據(jù)量就不會很大效果將更不明顯。

    ? ??add(int index, E element)

    ??? add(int index,E element)在指定位置插入元素。

    [java]?view plaincopy
  • 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++;??
  • ?????}??
  • ? ?首先判斷指定位置index是否超出elementData的界限,之后調(diào)用ensureCapacity調(diào)整容量(若容量足夠則不會拓展),調(diào)用System.arraycopy將elementData從index開始的size-index個元素復(fù)制到index+1至size+1的位置(即index開始的元素都向后移動一個位置),然后將index位置的值指向element。? ? ? ?

    ? ? addAll(Collection<? extends E> c)

    [java]?view plaincopy
  • public?boolean?addAll(Collection<??extends?E>?c)?{??
  • ?????Object[]?a?=?c.toArray();??
  • ?????????int?numNew?=?a.length;??
  • ?????ensureCapacity(size?+?numNew);??//?Increments?modCount??
  • ?????????System.arraycopy(a,?0,?elementData,?size,?numNew);??
  • ?????????size?+=?numNew;??
  • ?????return?numNew?!=?0;??
  • ?????}??
  • ? 先將集合c轉(zhuǎn)換成數(shù)組,根據(jù)轉(zhuǎn)換后數(shù)組的程度和ArrayList的size拓展容量,之后調(diào)用System.arraycopy方法復(fù)制元素到elementData的尾部,調(diào)整size。根據(jù)返回的內(nèi)容分析,只要集合c的大小不為空,即轉(zhuǎn)換后的數(shù)組長度不為0則返回true。

    ? ? addAll(int index,Collection<? extends E> c)

    [java]?view plaincopy
  • public?boolean?addAll(int?index,?Collection<??extends?E>?c)?{??
  • ?????if?(index?>?size?||?index?<?0)??
  • ?????????throw?new?IndexOutOfBoundsException(??
  • ?????????"Index:?"?+?index?+?",?Size:?"?+?size);??
  • ???
  • ?????Object[]?a?=?c.toArray();??
  • ?????int?numNew?=?a.length;??
  • ?????ensureCapacity(size?+?numNew);??//?Increments?modCount??
  • ???
  • ?????int?numMoved?=?size?-?index;??
  • ?????if?(numMoved?>?0)??
  • ?????????System.arraycopy(elementData,?index,?elementData,?index?+?numNew,??
  • ??????????????????numMoved);??
  • ???
  • ?????????System.arraycopy(a,?0,?elementData,?index,?numNew);??
  • ?????size?+=?numNew;??
  • ?????return?numNew?!=?0;??
  • ?????}??
  • ? 先判斷index是否越界。其他內(nèi)容與addAll(Collection<? extends E> c)基本一致,只是復(fù)制的時候先將index開始的元素向后移動X(c轉(zhuǎn)為數(shù)組后的長度)個位置(也是一個復(fù)制的過程),之后將數(shù)組內(nèi)容復(fù)制到elementData的index位置至index+X。

    ? ? clear()

    [java]?view plaincopy
  • public?void?clear()?{??
  • ?????modCount++;??
  • ???
  • ?????//?Let?gc?do?its?work??
  • ?????for?(int?i?=?0;?i?<?size;?i++)??
  • ?????????elementData[i]?=?null;??
  • ???
  • ?????size?=?0;??
  • ?????}??
  • clear的時候并沒有修改elementData的長度(好不容易申請、拓展來的,憑什么釋放,留著搞不好還有用呢。這使得確定不再修改list內(nèi)容之后最好調(diào)用trimToSize來釋放掉一些空間),只是將所有元素置為null,size設(shè)置為0。

    ? ? clone()

    ? ? 返回此 ArrayList 實(shí)例的淺表副本。(不復(fù)制這些元素本身。)

    [java]?view plaincopy
  • public?Object?clone()?{??
  • ?????try?{??
  • ?????????ArrayList<E>?v?=?(ArrayList<E>)?super.clone();??
  • ?????????v.elementData?=?Arrays.copyOf(elementData,?size);??
  • ?????????v.modCount?=?0;??
  • ?????????return?v;??
  • ?????}?catch?(CloneNotSupportedException?e)?{??
  • ?????????//?this?shouldn't?happen,?since?we?are?Cloneable??
  • ?????????throw?new?InternalError();??
  • ?????}??
  • ?????}??
  • ? 調(diào)用父類的clone方法返回一個對象的副本,將返回對象的elementData數(shù)組的內(nèi)容賦值為原對象elementData數(shù)組的內(nèi)容,將副本的modCount設(shè)置為0。

    ? ? contains(Object)

    [html]?view plaincopy
  • public?boolean?contains(Object?o)?{??
  • ?????return?indexOf(o)?>=?0;??
  • ?????}??
  • ?indexOf方法返回值與0比較來判斷對象是否在list中。接著看indexOf。

    ? ? indexOf(Object)

    [java]?view plaincopy
  • 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;??
  • ?????}??

  • 通過遍歷elementData數(shù)組來判斷對象是否在list中,若存在,返回index([0,size-1]),若不存在則返回-1。所以contains方法可以通過indexOf(Object)方法的返回值來判斷對象是否被包含在list中。

    ? ? 既然看了indexOf(Object)方法,接著就看lastIndexOf,光看名字應(yīng)該就明白了返回的是傳入對象在elementData數(shù)組中最后出現(xiàn)的index值。

    [java]?view plaincopy
  • 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;??
  • ?????}??
  • 采用了從后向前遍歷element數(shù)組,若遇到Object則返回index值,若沒有遇到,返回-1。

    ? ??get(int index)

    ? ? 這個方法看著很簡單,應(yīng)該是返回elementData[index]就完了。

    [java]?view plaincopy
  • public?E?get(int?index)?{??
  • ?????RangeCheck(index);??
  • ??
  • ?????return?(E)?elementData[index];??
  • ?????}??

  • 但看代碼的時候看到調(diào)用了RangeCheck方法,而且還是大寫的方法,看看究竟有什么內(nèi)容吧。

    [java]?view plaincopy
  • /**?
  • ??????*?Checks?if?the?given?index?is?in?range.?
  • ?*/??
  • ?private?void?RangeCheck(int?index)?{??
  • ?????if?(index?>=?size)??
  • ?????????throw?new?IndexOutOfBoundsException(??
  • ?????????"Index:?"+index+",?Size:?"+size);??
  • ?????}??

  • ?就是檢查一下是不是超出數(shù)組界限了,超出了就拋出IndexOutBoundsException異常。為什么要大寫呢???

    ? ? isEmpty()

    ? ? 直接返回size是否等于0。

    ? ? remove(int index)

    [java]?view plaincopy
  • 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;??
  • ?????}??

  • 首先是檢查范圍,修改modCount,保留將要被移除的元素,將移除位置之后的元素向前挪動一個位置,將list末尾元素置空(null),返回被移除的元素。

    ? ? remove(Object o)

    [java]?view plaincopy
  • 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;??
  • ?????}??

  • ? 首先通過代碼可以看到,當(dāng)移除成功后返回true,否則返回false。remove(Object o)中通過遍歷element尋找是否存在傳入對象,一旦找到就調(diào)用fastRemove移除對象。為什么找到了元素就知道了index,不通過remove(index)來移除元素呢?因?yàn)閒astRemove跳過了判斷邊界的處理,因?yàn)檎业皆鼐拖喈?dāng)于確定了index不會超過邊界,而且fastRemove并不返回被移除的元素。下面是fastRemove的代碼,基本和remove(index)一致。

    [java]?view plaincopy
  • private?void?fastRemove(int?index)?{??
  • ?????????modCount++;??
  • ?????????int?numMoved?=?size?-?index?-?1;??
  • ?????????if?(numMoved?>?0)??
  • ?????????????System.arraycopy(elementData,?index+1,?elementData,?index,??
  • ??????????????????????????????numMoved);??
  • ?????????elementData[--size]?=?null;?//?Let?gc?do?its?work??
  • ?????}??

  • ? removeRange(int fromIndex,int toIndex)

    [java]?view plaincopy
  • protected?void?removeRange(int?fromIndex,?int?toIndex)?{??
  • ?????modCount++;??
  • ?????int?numMoved?=?size?-?toIndex;??
  • ?????????System.arraycopy(elementData,?toIndex,?elementData,?fromIndex,??
  • ??????????????????????????numMoved);??
  • ???
  • ?????//?Let?gc?do?its?work??
  • ?????int?newSize?=?size?-?(toIndex-fromIndex);??
  • ?????while?(size?!=?newSize)??
  • ?????????elementData[--size]?=?null;??
  • ?????}??
  • 執(zhí)行過程是將elementData從toIndex位置開始的元素向前移動到fromIndex,然后將toIndex位置之后的元素全部置空順便修改size。

    ? ??這個方法是protected,及受保護(hù)的方法,為什么這個方法被定義為protected呢?

    ? ? 這是一個解釋,但是可能不容易看明白。http://stackoverflow.com/questions/2289183/why-is-javas-abstractlists-removerange-method-protected

    ? ? 先看下面這個例子

    [java]?view plaincopy
  • ArrayList<Integer>?ints?=?new?ArrayList<Integer>(Arrays.asList(0,?1,?2,??
  • ?????????????????3,?4,?5,?6));??
  • ?????????//?fromIndex?low?endpoint?(inclusive)?of?the?subList??
  • ?????????//?toIndex?high?endpoint?(exclusive)?of?the?subList??
  • ????????ints.subList(2,?4).clear();??
  • ?????????System.out.println(ints);??
  • ? 輸出結(jié)果是[0, 1, 4, 5, 6],結(jié)果是不是像調(diào)用了removeRange(int fromIndex,int toIndex)!哈哈哈,就是這樣的。但是為什么效果相同呢?是不是調(diào)用了removeRange(int fromIndex,int toIndex)呢?

    set(int index,E element)

    [java]?view plaincopy
  • public?E?set(int?index,?E?element)?{??
  • ?????RangeCheck(index);??
  • ???
  • ?????E?oldValue?=?(E)?elementData[index];??
  • ?????elementData[index]?=?element;??
  • ?????return?oldValue;??
  • ?????}??
  • ? 首先檢查范圍,用新元素替換舊元素并返回舊元素。

    ? ? size()

    ? ? size()方法直接返回size。

    ? ? toArray()

    [java]?view plaincopy
  • public?Object[]?toArray()?{??
  • ?????????return?Arrays.copyOf(elementData,?size);??
  • ?????}??
  • ?調(diào)用Arrays.copyOf將返回一個數(shù)組,數(shù)組內(nèi)容是size個elementData的元素,即拷貝elementData從0至size-1位置的元素到新數(shù)組并返回。

    ? ? toArray(T[] a)

    [java]?view plaincopy
  • public?<T>?T[]?toArray(T[]?a)?{??
  • ?????????if?(a.length?<?size)??
  • ?????????????//?Make?a?new?array?of?a's?runtime?type,?but?my?contents:??
  • ?????????????return?(T[])?Arrays.copyOf(elementData,?size,?a.getClass());??
  • ?????System.arraycopy(elementData,?0,?a,?0,?size);??
  • ?????????if?(a.length?>?size)??
  • ?????????????a[size]?=?null;??
  • ?????????return?a;??
  • ?????}??
  • ?如果傳入數(shù)組的長度小于size,返回一個新的數(shù)組,大小為size,類型與傳入數(shù)組相同。所傳入數(shù)組長度與size相等,則將elementData復(fù)制到傳入數(shù)組中并返回傳入的數(shù)組。若傳入數(shù)組長度大于size,除了復(fù)制elementData外,還將把返回?cái)?shù)組的第size個元素置為空。

    ? ? trimToSize()

    [java]?view plaincopy
  • public?void?trimToSize()?{??
  • ?????modCount++;??
  • ?????int?oldCapacity?=?elementData.length;??
  • ?????if?(size?<?oldCapacity)?{??
  • ?????????????elementData?=?Arrays.copyOf(elementData,?size);??
  • ?????}??
  • ?????}??
  • 由于elementData的長度會被拓展,size標(biāo)記的是其中包含的元素的個數(shù)。所以會出現(xiàn)size很小但elementData.length很大的情況,將出現(xiàn)空間的浪費(fèi)。trimToSize將返回一個新的數(shù)組給elementData,元素內(nèi)容保持不變,length很size相同,節(jié)省空間。

    ?? ? 學(xué)習(xí)Java最好的方式還必須是讀源碼。讀完源碼你才會發(fā)現(xiàn)這東西為什么是這么玩的,有哪些限制,關(guān)鍵點(diǎn)在哪里等等。而且這些源碼都是大牛們寫的,你能從中學(xué)習(xí)到很多。

    總結(jié)

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

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

    主站蜘蛛池模板: 亚洲精品国产精品乱码不99热 | 亚洲黄站| 国产一级二级三级视频 | av导航福利| 黄色大片日本 | 99国产超薄肉色丝袜交足 | 国产免费视频一区二区三区 | 天天干天天草 | 蜜臀精品一区二区三区 | 色哟哟入口 | 中文字幕1区 | 欧美精品videos另类日本 | 呦呦在线视频 | 亚洲区 欧美区 | 国产美女作爱视频 | 超碰人人擦 | 日本xxxxwwwww| 国产婷婷色一区二区 | 91香蕉一区二区三区在线观看 | 九九热在线播放 | 一级看片 | 日本精品久久久久久 | 欧美精品免费播放 | 波多野结衣二区 | 亚洲欧美激情在线观看 | av在线在线 | 黑人巨大精品欧美一区免费视频 | ass大乳尤物肉体pics | 亚洲AV成人无码精电影在线 | 国产欧美一区二区三区国产幕精品 | 欧美1页| 国产精品自拍视频一区 | 日韩在线视频网站 | 欧美日韩国产一区二区在线观看 | 日韩最新av| 国产a精品 | 亚洲av无码不卡一区二区三区 | 午夜小视频网站 | 91黑人精品一区二区三区 | 三上悠亚久久精品 | 91黄色国产 | 久久久性 | 日本三级吃奶头添泬 | 一级片欧美| 国产激情无码一区二区 | 亚洲一区二区三区四区电影 | 在线观看你懂的网站 | 黑人巨大精品欧美一区免费视频 | 日本激情视频在线观看 | 久草视频在线资源站 | 91亚洲精品久久久久久久久久久久 | 99re99| 无码国产伦一区二区三区视频 | 一女被多男玩喷潮视频 | 国产第9页| 国产精品免费av一区二区 | 福利视频网站 | 欧美久久久久久久久中文字幕 | 欧美另类z0zx974| 亚洲毛片久久 | 一本色道久久亚洲综合精品蜜桃 | 三上悠亚久久精品 | 好男人www日本 | 国产精品人人妻人人爽人人牛 | 波多野 在线 | 四虎影视成人永久免费观看亚洲欧美 | 亚洲精品一线二线三线 | 成人午夜影视在线观看 | 一级毛片基地 | 日本xxxxxwwwww| 91久久综合亚洲鲁鲁五月天 | 国产乱码精品一区二区三区中文 | 人成精品 | 国产学生美女无遮拦高潮视频 | 色射影院 | 鲁丝一区二区 | 欧美一级高潮片 | 亚洲一区二区三区免费视频 | 国产在线视频网站 | 久久久久久久亚洲av无码 | 亚洲bb| 欧美性在线视频 | 久久青青草原亚洲av无码麻豆 | 久久久欧洲| 国产精品久久一区 | 狠色综合7777夜色撩人 | 免费高清视频一区二区三区 | 亚洲大片免费 | 亚洲欧洲综合网 | 免费欧美黄色片 | 国产麻豆一区 | 国产女人18毛片水真多18精品 | av影院在线观看 | 欧美一区二区视频在线 | 精品一区二区三区四区五区六区 | 日本少妇裸体做爰高潮片 | 欧美另类极品videosbest使用方法 | 国产视频1区2区 | 成人免费看片又大又黄 |