Java集合是java提供的工具包,包含了常用的數(shù)據(jù)結(jié)構(gòu):集合、鏈表、隊(duì)列、棧、數(shù)組、映射等。Java集合工具包位置是java.util.*
Java集合主要可以劃分為4個(gè)部分:List列表、Set集合、Map映射、工具類(Iterator迭代器、Enumeration枚舉類、Arrays和Collections)。
Java集合工具包框架如下圖。

說明:看上面的框架圖,先抓住它的主干,即Collection和Map。
Collection是一個(gè)接口,是高度抽象出來的集合,它包含了集合的基本操作和屬性。
Collection包含了List和Set兩大分支。
(01) List(有序可重復(fù))是一個(gè)有序的隊(duì)列,每一個(gè)元素都有它的索引。第一個(gè)元素的索引值是0。
List的實(shí)現(xiàn)類有LinkedList, ArrayList, Vector, Stack。
(02) Set(無序不可重復(fù))是一個(gè)不允許有重復(fù)元素的集合。
Set的實(shí)現(xiàn)類有HastSet和TreeSet。HashSet依賴于HashMap,它實(shí)際上是通過HashMap實(shí)現(xiàn)的;TreeSet依賴于TreeMap,它實(shí)際上是通過TreeMap實(shí)現(xiàn)的。
Map是一個(gè)映射接口,即key-value鍵值對(duì)。Map中的每一個(gè)元素包含“一個(gè)key”和“key對(duì)應(yīng)的value”。
AbstractMap是個(gè)抽象類,它實(shí)現(xiàn)了Map接口中的大部分API。而HashMap,TreeMap,WeakHashMap都是繼承于AbstractMap。
Hashtable雖然繼承于Dictionary,但它實(shí)現(xiàn)了Map接口。
接下來,再看Iterator。它是遍歷集合的工具,即我們通常通過Iterator迭代器來遍歷集合。我們說Collection依賴于Iterator,是因?yàn)镃ollection的實(shí)現(xiàn)類都要實(shí)現(xiàn)iterator()函數(shù),返回一個(gè)Iterator對(duì)象。
ListIterator是專門為遍歷List而存在的。
再看Enumeration,它是JDK 1.0引入的抽象類。作用和Iterator一樣,也是遍歷集合;但是Enumeration的功能要比Iterator少。在上面的框圖中,Enumeration只能在Hashtable, Vector, Stack中使用。
最后,看Arrays和Collections。它們是操作數(shù)組、集合的兩個(gè)工具類。
有了上面的整體框架之后,我們接下來對(duì)每個(gè)類分別進(jìn)行分析。
Collection架構(gòu)
下面,我們將對(duì)Collection進(jìn)行概括。下面先看看Collection的一些框架類的關(guān)系圖:

Collection是一個(gè)接口,它主要的兩個(gè)分支是:List 和 Set。
List和Set都是接口,它們繼承于Collection。List是有序的隊(duì)列,List中可以有重復(fù)的元素;而Set是數(shù)學(xué)概念中的集合,Set中沒有重復(fù)元素!
List和Set都有它們各自的實(shí)現(xiàn)類。
為了方便實(shí)現(xiàn),集合中定義了AbstractCollection抽象類,它實(shí)現(xiàn)了Collection中的絕大部分函數(shù);這樣,在Collection的實(shí)現(xiàn)類中,我們就可以通過繼承AbstractCollection省去重復(fù)編碼。AbstractList和AbstractSet都繼承于AbstractCollection,具體的List實(shí)現(xiàn)類繼承于AbstractList,而Set的實(shí)現(xiàn)類則繼承于AbstractSet。
另外,Collection中有一個(gè)iterator()函數(shù),它的作用是返回一個(gè)Iterator接口。通常,我們通過Iterator迭代器來遍歷集合。ListIterator是List接口所特有的,在List接口中,通過ListIterator()返回一個(gè)ListIterator對(duì)象。
接下來,我們看看各個(gè)接口和抽象類的介紹;然后,再對(duì)實(shí)現(xiàn)類進(jìn)行詳細(xì)的了解。
1. Collection簡(jiǎn)介
Collection的定義如下:

它是一個(gè)接口,是高度抽象出來的集合,它包含了集合的基本操作:添加、刪除、清空、遍歷(讀取)、是否為空、獲取大小、是否保護(hù)某元素等等。
Collection接口的所有子類(直接子類和間接子類)都必須實(shí)現(xiàn)2種構(gòu)造函數(shù):不帶參數(shù)的構(gòu)造函數(shù) 和 參數(shù)為Collection的構(gòu)造函數(shù)。帶參數(shù)的構(gòu)造函數(shù),可以用來轉(zhuǎn)換Collection的類型。

2. List簡(jiǎn)介
List的定義如下:

List是一個(gè)繼承于Collection的接口,即List是集合中的一種。List是有序的隊(duì)列,List中的每一個(gè)元素都有一個(gè)索引;第一個(gè)元素的索引值是0,往后的元素的索引值依次+1。和Set不同,List中允許有重復(fù)的元素。 List的官方介紹如下:
A List is a collection which maintains an ordering for its elements. Every element in the List has an index. Each element can thus be accessed by its index, with the first index being zero. Normally, Lists allow duplicate elements, as compared to Sets, where elements have to be unique.
關(guān)于API方面。既然List是繼承于Collection接口,它自然就包含了Collection中的全部函數(shù)接口;由于List是有序隊(duì)列,它也額外的有自己的API接口。主要有“添加、刪除、獲取、修改指定位置的元素”、“獲取List中的子隊(duì)列”等。

3. Set簡(jiǎn)介
Set的定義如下:

Set是一個(gè)繼承于Collection的接口,即Set也是集合中的一種。Set是沒有重復(fù)元素的集合。
關(guān)于API方面。Set的API和Collection完全一樣。

4. AbstractCollection
AbstractCollection的定義如下:

AbstractCollection是一個(gè)抽象類,它實(shí)現(xiàn)了Collection中除iterator()和size()之外的函數(shù)。
AbstractCollection的主要作用:它實(shí)現(xiàn)了Collection接口中的大部分函數(shù)。從而方便其它類實(shí)現(xiàn)Collection,比如ArrayList、LinkedList等,它們這些類想要實(shí)現(xiàn)Collection接口,通過繼承AbstractCollection就已經(jīng)實(shí)現(xiàn)了大部分的接口了。
5. AbstractList
AbstractList的定義如下:
public? ? abstract? ?class? AbstractList<E>? extends AbstractCollection<E>? ? implements List<E> {}
AbstractList是一個(gè)繼承于AbstractCollection,并且實(shí)現(xiàn)List接口的抽象類。它實(shí)現(xiàn)了List中除size()、get(int location)之外的函數(shù)。
AbstractList的主要作用:它實(shí)現(xiàn)了List接口中的大部分函數(shù)。從而方便其它類繼承List。
另外,和AbstractCollection相比,AbstractList抽象類中,實(shí)現(xiàn)了iterator()接口。
6. AbstractSet
AbstractSet的定義如下:
public? ? ?abstract? ? class? ? ? AbstractSet<E>? ? extends? ? AbstractCollection<E>?? implements? Set<E> {}
AbstractSet是一個(gè)繼承于AbstractCollection,并且實(shí)現(xiàn)Set接口的抽象類。由于Set接口和Collection接口中的API完全一樣,Set也就沒有自己?jiǎn)为?dú)的API。和AbstractCollection一樣,它實(shí)現(xiàn)了List中除iterator()和size()之外的函數(shù)。
AbstractSet的主要作用:它實(shí)現(xiàn)了Set接口中的大部分函數(shù)。從而方便其它類實(shí)現(xiàn)Set接口。
7. Iterator
Iterator的定義如下:

Iterator是一個(gè)接口,它是集合的迭代器。集合可以通過Iterator去遍歷集合中的元素。Iterator提供的API接口,包括:是否存在下一個(gè)元素、獲取下一個(gè)元素、刪除當(dāng)前元素。
注意:Iterator遍歷Collection時(shí),是fail-fast機(jī)制的。即,當(dāng)某一個(gè)線程A通過iterator去遍歷某集合的過程中,若該集合的內(nèi)容被其他線程所改變了;那么線程A訪問集合時(shí),就會(huì)拋出ConcurrentModificationException異常,產(chǎn)生fail-fast事件。關(guān)于fail-fast的詳細(xì)內(nèi)容,我們會(huì)在fail-fast總結(jié)后面專門進(jìn)行說明。

8. ListIterator
ListIterator的定義如下:

ListIterator是一個(gè)繼承于Iterator的接口,它是隊(duì)列迭代器。專門用于便利List,能提供向前/向后遍歷。相比于Iterator,它新增了添加、是否存在上一個(gè)元素、獲取上一個(gè)元素等等API接口。

以上轉(zhuǎn)載:www.jb51.net/article/84821.htm
常見面試題:
1.Collection和Collections的差別?
? ??????java.util.Collection 是一個(gè)集合接口,Collection接口在Java類庫(kù)中有非常多詳細(xì)的實(shí)現(xiàn)。比如List、Set;
????????java.util.Collections 是針對(duì)集合類的一個(gè)幫助類,它提供了一系列的靜態(tài)方法實(shí)現(xiàn)對(duì)各種集合的搜索、排序、線程安全化等操作。
2、List與Map的差別?
List是存儲(chǔ)單列數(shù)據(jù)的集合,Map是存儲(chǔ)key和value這樣雙列數(shù)據(jù)的集合,List中存儲(chǔ)的數(shù)據(jù)是有順序的,而且同意反復(fù)。
Map其中存儲(chǔ)的數(shù)據(jù)是沒有順序的,它存儲(chǔ)的key是不能反復(fù)的,value是能夠反復(fù)的。
List繼承Collection接口,Map不是。Map沒有父類
3.List、Map、Set三個(gè)接口。存取元素時(shí)各有什么特點(diǎn)
首先List和Set都是單列元素的集合。它們有一個(gè)共同的父接口Collection。
List內(nèi)的元素講究有序性。內(nèi)部元素可反復(fù)??墒荢et恰恰相反。它講究的是無序性,元素不可反復(fù)。Set的add方法有一個(gè)boolean的返回值,每當(dāng)add一個(gè)新元
素的時(shí)候都會(huì)調(diào)用equals方法進(jìn)行逐一比較,當(dāng)新元素與全部的已存在元素的都不反復(fù)的時(shí)候add成功返回true。否則返回false。
Map與List和Set不同,它是雙列存儲(chǔ)的(鍵和值一一相應(yīng))。它在存儲(chǔ)元素調(diào)用的是put方法,每次存儲(chǔ)時(shí),要存儲(chǔ)一份key和value。不能存儲(chǔ)反復(fù)的key,這個(gè)反復(fù)的規(guī)則也是利用equals進(jìn)行比較。取數(shù)據(jù)的時(shí)候則能夠依據(jù)key獲取value。另外還是以獲得全部key的集合和全部value的集合。還能夠獲得key和value組成的Map.Entry對(duì)象的集合。
4.ArrayList與LinkedList的區(qū)別?
ArrayList和LinkedList兩者都實(shí)現(xiàn)了List接口,但是它們之間有些不同。
(1)ArrayList是由Array所支持的基于一個(gè)索引的數(shù)據(jù)結(jié)構(gòu),所以它提供對(duì)元素的隨機(jī)訪問,復(fù)雜度為O(1),但LinkedList存儲(chǔ)一系列的節(jié)點(diǎn)數(shù)據(jù),每個(gè)節(jié)點(diǎn)都與前一個(gè)和下一個(gè)節(jié)點(diǎn)相連接。所以,盡管有使用索引獲取元素的方法,內(nèi)部實(shí)現(xiàn)是從起始點(diǎn)開始遍歷,遍歷到索引的節(jié)點(diǎn)然后返回元素,時(shí)間復(fù)雜度為O(n),比ArrayList要慢。
(2)與ArrayList相比,在LinkedList中插入、添加和刪除一個(gè)元素會(huì)更快,因?yàn)樵谝粋€(gè)元素被插入到中間的時(shí)候,不會(huì)涉及改變數(shù)組的大小,或更新索引。
(3)LinkedList比ArrayList消耗更多的內(nèi)存,因?yàn)長(zhǎng)inkedList中的每個(gè)節(jié)點(diǎn)存儲(chǔ)了前后節(jié)點(diǎn)的引用。
5.ArrayList與Vector的區(qū)別?
這兩個(gè)類都實(shí)現(xiàn)了List接口(List接口繼承自Collection接口)。它們都是有序集合。它們內(nèi)部的元素都是能夠反復(fù)的,都能夠依據(jù)序號(hào)取出當(dāng)中的某一元素。
它們兩個(gè)的差別在于:
(1)、線程安全的問題:
????????Vector是早期Java就有的,是同意多線程操作的。是線程安全的;而ArrayList是在Java2中才出現(xiàn),它是線程不安全的,僅僅能使用單線程操作。 因?yàn)閂ector支持多線程操作,所以在性能上就比不上ArrayList了。(相同的HashTable相比于HashMap也是支持多線程的操作而導(dǎo)致性能不如HashMap。)
(2)、數(shù)據(jù)增長(zhǎng)的問題
????????ArrayList和Vector都有一個(gè)初始的容量大小,當(dāng)存儲(chǔ)進(jìn)去它們里面的元素個(gè)數(shù)超出容量的時(shí)候。就須要添加ArrayList和Vector的存儲(chǔ)空間,每次添加存儲(chǔ)空間的時(shí)候不是僅僅添加一個(gè)存儲(chǔ)單元。是添加多個(gè)存儲(chǔ)單元。
Vector默認(rèn)添加原來的一倍,ArrayList默認(rèn)添加原來的0.5倍。
Vector能夠由我們自己來設(shè)置增長(zhǎng)的大小,ArrayList沒有提供相關(guān)的方法。
6.HashMap與HashTable的區(qū)別?
(1)HashMap允許key和value為null,而HashTable不允許。
(2)HashTable是同步的,而HashMap不是。所以HashMap適合單線程環(huán)境,HashTable適合多線程環(huán)境。
(3)在Java1.4中引入了LinkedHashMap,HashMap的一個(gè)子類,假如你想要遍歷順序,你很容易從HashMap轉(zhuǎn)向LinkedHashMap,但是HashTable不是這樣的,它的順序是不可預(yù)知的。
(4)HashMap提供對(duì)key的Set進(jìn)行遍歷,因此它是fail-fast的,但HashTable提供對(duì)key的Enumeration進(jìn)行遍歷,它不支持fail-fast。
(5)HashTable被認(rèn)為是個(gè)遺留的類,如果你尋求在迭代的時(shí)候修改Map,你應(yīng)該使用CocurrentHashMap。
7.如何決定選用HashMap還是TreeMap?
對(duì)于在Map中插入、刪除和定位元素這類操作,HashMap是最好的選擇。然而,假如你需要對(duì)一個(gè)有序的key集合進(jìn)行遍歷,TreeMap是更好的選擇?;谀愕腸ollection的大小,也許向HashMap中添加元素會(huì)更快,將map換為TreeMap進(jìn)行有序key的遍歷。
8.哪些集合類提供對(duì)元素的隨機(jī)訪問?
ArrayList、HashMap、TreeMap和HashTable類提供對(duì)元素的隨機(jī)訪問。
9.哪些集合類是線程安全的?
Vector、HashTable、Properties和Stack是同步類,所以它們是線程安全的,可以在多線程環(huán)境下使用。Java1.5并發(fā)API包括一些集合類,允許迭代時(shí)修改,因?yàn)樗鼈兌脊ぷ髟诩系目寺∩希运鼈冊(cè)诙嗑€程環(huán)境中是安全的。
10.并發(fā)集合類是什么?
????????Java1.5并發(fā)包(java.util.concurrent)包含線程安全集合類,允許在迭代時(shí)修改集合。迭代器被設(shè)計(jì)為fail-fast的,會(huì)拋出ConcurrentModificationException。一部分類為:CopyOnWriteArrayList、 ConcurrentHashMap、CopyOnWriteArraySet。
11.隊(duì)列和棧是什么,列出它們的區(qū)別?
棧和隊(duì)列兩者都被用來預(yù)存儲(chǔ)數(shù)據(jù)。java.util.Queue是一個(gè)接口,它的實(shí)現(xiàn)類在Java并發(fā)包中。隊(duì)列允許先進(jìn)先出(FIFO)檢索元素,但并非總是這樣。Deque接口允許從兩端檢索元素。
棧與隊(duì)列很相似,但它允許對(duì)元素進(jìn)行后進(jìn)先出(LIFO)進(jìn)行檢索。
Stack是一個(gè)擴(kuò)展自Vector的類,而Queue是一個(gè)接口。
12.Comparable和Comparator接口是什么?
????????如果我們想使用Array或Collection的排序方法時(shí),需要在自定義類里實(shí)現(xiàn)Java提供Comparable接口。Comparable接口有compareTo(T OBJ)方法,它被排序方法所使用。我們應(yīng)該重寫這個(gè)方法,如果“this”對(duì)象比傳遞的對(duì)象參數(shù)更小、相等或更大時(shí),它返回一個(gè)負(fù)整數(shù)、0或正整數(shù)。但是,在大多數(shù)實(shí)際情況下,我們想根據(jù)不同參數(shù)進(jìn)行排序。比如,作為一個(gè)CEO,我想對(duì)雇員基于薪資進(jìn)行排序,一個(gè)HR想基于年齡對(duì)他們進(jìn)行排序。這就是我們需要使用Comparator接口的情景,因?yàn)镃omparable.compareTo(Object o)方法實(shí)現(xiàn)只能基于一個(gè)字段進(jìn)行排序,我們不能根據(jù)對(duì)象排序的需要選擇字段。Comparator接口的compare(Object o1, Object o2)方法的實(shí)現(xiàn)需要傳遞兩個(gè)對(duì)象參數(shù),若第一個(gè)參數(shù)比第二個(gè)小,返回負(fù)整數(shù);若第一個(gè)等于第二個(gè),返回0;若第一個(gè)比第二個(gè)大,返回正整數(shù)。
13..Comparable和Comparator接口有何區(qū)別?
Comparable和Comparator接口被用來對(duì)對(duì)象集合或者數(shù)組進(jìn)行排序。Comparable接口被用來提供對(duì)象的自然排序,我們可以使用它來提供基于單個(gè)邏輯的排序。
Comparator接口被用來提供不同的排序算法,我們可以選擇需要使用的Comparator來對(duì)給定的對(duì)象集合進(jìn)行排序。
14.hashCode()和equals()方法有何重要性?
HashMap使用Key對(duì)象的hashCode()和equals()方法去決定key-value對(duì)的索引。當(dāng)我們?cè)囍鴱腍ashMap中獲取值的時(shí)候,這些方法也會(huì)被用到。如果這些方法沒有被正確地實(shí)現(xiàn),在這種情況下,兩個(gè)不同Key也許會(huì)產(chǎn)生相同的hashCode()和equals()輸出,HashMap將會(huì)認(rèn)為它們是相同的,然后覆蓋它們,而非把它們存儲(chǔ)到不同的地方。同樣的,所有不允許存儲(chǔ)重復(fù)數(shù)據(jù)的集合類都使用hashCode()和equals()去查找重復(fù),所以正確實(shí)現(xiàn)它們非常重要。equals()和hashCode()的實(shí)現(xiàn)應(yīng)該遵循以下規(guī)則:
(1)如果o1.equals(o2),那么o1.hashCode() == o2.hashCode()總是為true的。
(2)如果o1.hashCode() == o2.hashCode(),并不意味著o1.equals(o2)會(huì)為true。
15.通過迭代器fail-fast屬性,你明白了什么?
每次我們嘗試獲取下一個(gè)元素的時(shí)候,Iterator fail-fast屬性檢查當(dāng)前集合結(jié)構(gòu)里的任何改動(dòng)。如果發(fā)現(xiàn)任何改動(dòng),它拋出ConcurrentModificationException。Collection中所有Iterator的實(shí)現(xiàn)都是按fail-fast來設(shè)計(jì)的(ConcurrentHashMap和CopyOnWriteArrayList這類并發(fā)集合類除外)。
16.fail-fast與fail-safe有什么區(qū)別?
Iterator的fail-fast屬性與當(dāng)前的集合共同起作用,因此它不會(huì)受到集合中任何改動(dòng)的影響。Java.util包中的所有集合類都被設(shè)計(jì)為fail-fast的,而java.util.concurrent中的集合類都為fail-safe的。Fail-fast迭代器拋出ConcurrentModificationException,而fail-safe迭代器從不拋出ConcurrentModificationException。
集合詳細(xì)轉(zhuǎn)自:
http://blog.csdn.net/w369033345/article/details/52187411
https://www.cnblogs.com/tlnshuju/archive/2017/04/18/6729467.html
http://www.importnew.com/15980.html
接下來詳細(xì)介紹下集合中不同集合的區(qū)別以及底層原理:
一、ArrayList的實(shí)現(xiàn)原理?
1、ArrayList概述?
ArrayList 是?List 接口的可變數(shù)組的實(shí)現(xiàn)。實(shí)現(xiàn)了所有可選列表操作,并允許包括?null 在內(nèi)的所有元素。除了實(shí)現(xiàn)List接口外,此類還提供一些方法來操作內(nèi)部用來存儲(chǔ)列表的數(shù)組的大小。每個(gè)ArrayList實(shí)例都有一個(gè)容量,該容量是指用來存儲(chǔ)列表元素的數(shù)組的大小。它總是至少等于列表的大小。隨著向ArrayList中不斷添加元素,其容量也自動(dòng)增長(zhǎng)。自動(dòng)增長(zhǎng)會(huì)帶來數(shù)據(jù)向新數(shù)組的重新拷貝,因此,如果可預(yù)知數(shù)據(jù)量的多少,可在構(gòu)造ArrayList時(shí)指定其容量。在添加大量元素前,應(yīng)用程序也可以使用ensureCapacity操作來增加ArrayList實(shí)例的容量,這可以減少遞增式再分配的數(shù)量。
注意,此實(shí)現(xiàn)不是同步的。如果多個(gè)線程同時(shí)訪問一個(gè)ArrayList實(shí)例,而其中至少一個(gè)線程從結(jié)構(gòu)上修改了列表,那么它必須保持外部同步。
2. ArrayList 的實(shí)現(xiàn)
對(duì)于ArrayList而言,它實(shí)現(xiàn)List接口、底層使用數(shù)組保存所有元素。其操作基本上是對(duì)數(shù)組的操作。下面我們來分析ArrayList的源代碼:
1) 底層使用數(shù)組實(shí)現(xiàn)
Java 代碼

2)構(gòu)造方法:
ArrayList 提供了三種方式的構(gòu)造器,可以構(gòu)造一個(gè)默認(rèn)初始容量為?10 的空列表、構(gòu)造一個(gè)指定初始容量的空列表以及構(gòu)造一個(gè)包含指定collection的元素的列表,這些元素按照該collection的迭代器返回它們的順序排列的。
Java 代碼
a:構(gòu)造一個(gè)默認(rèn)初始容量為?10?的空列表的構(gòu)造器:


b:構(gòu)造一個(gè)指定初始容量的空列表的構(gòu)造器

c:構(gòu)造一個(gè)包含指定collection的元素的列表的構(gòu)造器

注:詳細(xì)可見ArrayList的源碼。

3)存儲(chǔ)
????????ArrayList 提供了?set(int index, E element)、add(E e)、add(int index, E element)、addAll(Collection?c)、addAll(int index, Collection c)這些添加元素的方法。
下面我們一一講解:
Java 代碼





以上均是ArrayList的源碼,有興趣的可以看一下,有助于理解。
4)讀取
java 代碼

5)刪除
ArrayList 提供了根據(jù)下標(biāo)或者指定對(duì)象兩種方式的刪除功能。如下:
java 代碼
第一種:

第二種:

注意:從數(shù)組中移除元素的操作,也會(huì)導(dǎo)致被移除的元素以后的所有元素的向左移動(dòng)一個(gè)位置。
6)調(diào)整數(shù)組容量:
? ??????從上面介紹的向ArrayList中存儲(chǔ)元素的代碼中,我們看到,每當(dāng)向數(shù)組中添加元素時(shí),都要去檢查添加后元素的個(gè)數(shù)是否會(huì)超出當(dāng)前數(shù)組的長(zhǎng)度,如果超出,數(shù)組將會(huì)進(jìn)行擴(kuò)容,以滿足添加數(shù)據(jù)的需求。數(shù)組擴(kuò)容通過一個(gè)公開的方法ensureCapacity(int minCapacity)來實(shí)現(xiàn)。在實(shí)際添加大量元素前,我也可以使用ensureCapacity來手動(dòng)增加ArrayList實(shí)例的容量,以減少遞增式再分配的數(shù)量。


從上述代碼中可以看出,數(shù)組進(jìn)行擴(kuò)充時(shí),會(huì)將數(shù)組中的元素重新拷貝一份到新的數(shù)組中,每次數(shù)組容量的增長(zhǎng)大約是其容量的1.5倍。這種操作的代價(jià)是很高的,因此在實(shí)際使用中,我們應(yīng)該盡量避免數(shù)組容量的擴(kuò)張。當(dāng)我們可預(yù)知要保存的元素的多少是,要在構(gòu)造ArrayList實(shí)例時(shí),就指定其容量,以避免擴(kuò)容的發(fā)生?;蛘吒鶕?jù)實(shí)際需求,通過調(diào)用ensureCapacity方法來手動(dòng)增加ArrayList實(shí)例的容量。
? ? ? ? ArrayList還給我們提供了將底層數(shù)組的容量調(diào)整為當(dāng)前列表保存的實(shí)際元素的大小的功能。它可以通過trimToSize方法來實(shí)現(xiàn)。代碼如下:

7)Fail-Fast機(jī)制
????????ArrayList也采用了快速失敗的機(jī)制,通過記錄modCount參數(shù)來實(shí)現(xiàn)。在面對(duì)并發(fā)的修改時(shí),迭代器很快就會(huì)完全失敗,而不是冒著將來某個(gè)不確定時(shí)間發(fā)生任意不確定行為的風(fēng)險(xiǎn)。