日韩性视频-久久久蜜桃-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)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 三级黄色短视频 | 辟里啪啦国语版免费观看 | 欧美性生活网 | 国产亚洲一区二区不卡 | 制服丝袜第一页在线观看 | 亚洲女同一区二区 | 乱人伦中文字幕 | 国产成人激情视频 | 嫩草视频在线观看 | av天天操 | 久久亚洲av午夜福利精品一区 | 欧美日韩国产免费一区二区三区 | 天天躁日日躁狠狠躁免费麻豆 | 少妇被黑人到高潮喷出白浆 | 精品人伦一区二区三区蜜桃网站 | 欧美人妻一区二区三区 | 性史性dvd影片农村毛片 | 成年人在线播放 | 日韩尤物 | 日本亚洲色大成网站www久久 | 在线观看国产精品入口男同 | fc2成人免费视频 | 成人免费毛片东京热 | 成人黄色性视频 | 性欧美在线| 亚洲视频小说 | 国产精品久久久久久久免费 | 日韩色综合网 | 国产精品69久久久久孕妇欧美 | 麻豆传媒在线视频 | 蜜桃成人无码区免费视频网站 | 国产成人一区二区三区电影 | 久久婷婷综合国产 | 手机看片在线观看 | 日韩精品字幕 | 久久精品国产视频 | 亚洲第一在线视频 | 中文字幕日韩精品一区 | 国产综合视频一区二区 | 男女黄床上色视频免费的软件 | 日本一二三区视频在线 | 少妇被狂c下部羞羞漫画 | 免费 成 人 黄 色 | 亚洲第一中文字幕 | 中日毛片 | 国产精品成人免费精品自在线观看 | 亚洲永久精品一区二区 | 黑人中文字幕一区二区三区 | 欧美日韩在线视频一区二区三区 | 激情xxx | 二区久久 | 色吊丝av中文字幕 | 五月亚洲婷婷 | 丰满少妇麻豆av苏语棠 | 久久99国产精品 | 亚洲综合五月天婷婷丁香 | 天堂а√在线最新版中文在线 | 欧美另类69 | 深夜激情网 | 日日干日日 | 黄色香蕉软件 | 久久午夜国产精品 | 男女一区 | 最新精品国产 | 精品国产av一区二区 | 一级全黄男女免费大片 | 亚洲乱亚洲乱妇 | 18性xxxxx性猛交 | 欧美一级高清片 | 国产成人久久婷婷精品流白浆 | 黄色一级片网站 | 国产男男一区二区三区 | 中文字幕在线免费播放 | 国产自在线 | 亚洲第一成人av | 日韩视频在线观看一区二区三区 | 亚洲一卡二卡在线 | 在线免费观看污片 | 国产一区两区 | 欧美性受xxxx黑人xyx性爽 | 免费看污黄网站在线观看 | 三及毛片 | 一区二区三区播放 | 日本成人午夜 | 玖玖视频国产 | 久久精品五月天 | 国产又大又长又粗 | 99爱在线 | 国产精品永久在线观看 | 国产一区二区三区视频在线播放 | 天天操妹子| 国产精品久久久久高潮 | 亚洲在线激情 | 91亚洲精品久久久蜜桃网站 | 久久精品在线播放 | 中文字幕免费在线观看 | 黄黄视频在线观看 | 欧美精品片 | 福利视频免费观看 |