1.java集合接口
集合類在java.util包下,主要有Set、List和Map
Collection:Collection 是集合 List、Set、Queue 的最基本的接口。
Iterator:迭代器,可以通過迭代器遍歷集合中的數(shù)據(jù)
Map:是映射表的基礎(chǔ)接口


2.List
List是非常常用的集合,它里面的元素是可重復(fù)且有序的,主要有三個(gè)實(shí)現(xiàn)類分別是:ArrayList、Vector、LinkedList。
3.ArrayList
數(shù)據(jù)結(jié)構(gòu):底層是用數(shù)組實(shí)現(xiàn)的,利用數(shù)組連續(xù)下標(biāo)的特性可以快速讀取對(duì)應(yīng)的元素
擴(kuò)容機(jī)制:當(dāng)容量不足需要擴(kuò)容時(shí),通過復(fù)制元素到新的數(shù)組。
線程安全:否
特點(diǎn):查詢快,利用數(shù)據(jù)的連續(xù)下標(biāo)特點(diǎn),增刪慢,因?yàn)樵鰟h后需要對(duì)數(shù)組進(jìn)行復(fù)制,移動(dòng)。所以適合查多寫少的場景。
4.Vector
Vector和ArrayList一樣底層都是數(shù)組實(shí)現(xiàn)的,不同的是Vector是線程安全的。也就是說同一時(shí)刻只能由一個(gè)線程對(duì)Vector進(jìn)行寫,避免了多線程操作的數(shù)據(jù)安全問題,同時(shí)由于加鎖的操作也使得性能低于ArrayList。
5.LinkedList
數(shù)據(jù)結(jié)構(gòu):雙向鏈表結(jié)構(gòu),增刪比較快只要修改前后指針的指向,讀取由于沒有下標(biāo)需要遍歷讀
擴(kuò)容機(jī)制:自動(dòng)擴(kuò)容
線程安全:否
特點(diǎn):適合動(dòng)態(tài)的增刪,隨機(jī)讀取速度比較慢,另外還提供了操作頭尾元素的方法,很適合做堆棧,隊(duì)列或雙向隊(duì)列。
6.Set
Set主要是側(cè)重元素的唯一性,且無序的,存入和讀取不一定一樣。保證唯一性主要是通過hashCode來保證,java對(duì)象的hashCode是通過內(nèi)存地址來計(jì)算的哈希值。如果想讓兩個(gè)不同的對(duì)象視為相等就要重寫Object的hashCode方法和equals方法。
7.HashSet
HashSet數(shù)據(jù)的存儲(chǔ)和讀取是根據(jù)哈希值來計(jì)算的,是無序的。HashSet會(huì)先判斷hashCode方法是否一樣,如果不一樣就是不同對(duì)象,如果一樣還要繼續(xù)判斷equals方法的返回結(jié)果,true就認(rèn)為是同一個(gè)對(duì)象,false就是不同對(duì)象。但是他們的存儲(chǔ)是有所不同的。
hashCode不同:

hashCode一樣,equals返回false:

也就是說一個(gè)哈希值的位置上可以存放多個(gè)元素,只不過他們形成一個(gè)鏈表或者說放到一個(gè)哈希桶中。
8.TreeSet
TreeSet是以二叉樹結(jié)構(gòu)來存放,每新增一個(gè)對(duì)象都會(huì)按升序或降序存放到二叉樹指定位置。
但是升序降序要實(shí)現(xiàn)Comparable接口重新compareTo()方法,Integer和String可以進(jìn)行默認(rèn)排序。
9.LinkedHashSet
LinkedHashSet實(shí)際上就是集成了HashSet,結(jié)構(gòu)又是用LinkedHashMap來存儲(chǔ),說白了就是只用到Map的key部分。所以LinkedHashSet的方法和HashSet幾乎一樣,只是提供了幾個(gè)構(gòu)造函數(shù),構(gòu)造函數(shù)調(diào)用父構(gòu)造函數(shù)初始化LinkedHashMap來做數(shù)據(jù)存儲(chǔ)。
10.HashMap
Map是存放鍵值對(duì)數(shù)據(jù),HashMap的key不允許重復(fù),允許為null,但是只有一個(gè)null,value可以重復(fù)也可以為null。正常情況下通過哈希值都能快速讀取到元素,但是遍歷的順序是不一定的。HashMap是非線程安全的。hashMap有幾個(gè)比較重要的屬性1. capacity:當(dāng)前數(shù)組容量,始終保持 2^n,可以擴(kuò)容,擴(kuò)容后數(shù)組大小為當(dāng)前的 2 倍。2. loadFactor:負(fù)載因子,默認(rèn)為 0.75。3. threshold:擴(kuò)容的閾值,等于 capacity * loadFactor。
不同版本的jdk,hashMap的結(jié)構(gòu)有所區(qū)別
jdk1.7版本主要是哈希+鏈表的結(jié)構(gòu)

大體上看是一個(gè)數(shù)組結(jié)構(gòu)當(dāng)哈希值沖突的時(shí)候在對(duì)應(yīng)位置演變成一個(gè)鏈表結(jié)構(gòu),鏈表結(jié)構(gòu)存的是Entry對(duì)象包括key,value,哈希值和next信息。
jdk1.8版本主要是哈希+鏈表+紅黑樹的結(jié)構(gòu)

jdk1.8對(duì)hashMap的結(jié)構(gòu)進(jìn)行了優(yōu)化,1.7中哈希沖突的的時(shí)候在對(duì)應(yīng)位置上演變鏈表位置,那查找的時(shí)候鏈表上的元素的時(shí)候時(shí)間復(fù)雜度就是O(n),取決于鏈表的長度。1.8中在鏈表的長度超過8的時(shí)候?qū)㈡湵硌葑兂杉t黑樹,自然查找的效率就高很多。
11.ConcurrentHashMap
ConcurrentHashMap和HashMap的結(jié)構(gòu)差不多,但是呢它是線程安全的,所以為了解決這個(gè)線程安全又想效率維持在較高的水平,就多了分段的概念。整個(gè)ConcurrentHashMap是有一個(gè)個(gè)分段Segment組成,Segment通過繼承ReentrantLock來進(jìn)行對(duì)該分段進(jìn)行加鎖,該分段里的數(shù)據(jù)結(jié)構(gòu)跟HashMap幾乎一樣。

在jdk1.8中鏈表超過8也是演變成紅黑樹。
ConcurrentHashMap 有 16 個(gè) Segments,所以理論上,這個(gè)時(shí)候,最多可以同時(shí)支
持 16 個(gè)線程并發(fā)寫,只要它們的操作分別分布在不同的 Segment 上。這個(gè)值可以在初始化的時(shí)
候設(shè)置為其他值,但是一旦初始化以后,它是不可以擴(kuò)容的。
12.HashTable
HashTable現(xiàn)在幾乎不使用了,他的功能和HashMap一樣,是線程安全的,但是加鎖的粒度比較大性能不是很高,如果想要線程安全就用ConcurrentHashMap,不在乎線程安全的場景就用HashMap。
13.TreeMap
TreeMap實(shí)現(xiàn)了SortedMap接口,支持根據(jù)key進(jìn)行排序,默認(rèn)是按鍵值的升序排序,也可以指定排序的比較器,在使用 TreeMap 時(shí),key 必須實(shí)現(xiàn) Comparable 接口或者在構(gòu)造 TreeMap 傳入自定義的
Comparator,否則會(huì)在運(yùn)行時(shí)拋出 java.lang.ClassCastException 類型的異常。