一、集合類也叫做容器類。它的功能至關於一個容器。能夠存儲數量不肯定的數據,以及保存具備映射關係的數據(也被稱爲關聯數組)。算法
二、Java的集合(容器),它是用來」裝對象的「(其實是對象的引用,但習慣上都稱爲對象)。數組
三、Java集合大體能夠分爲Set、List、Queue和Map四種體系。Set表明無序、不可重複的集合;List表明有序、容許重複的集合;而Map表明具備映射關係的集合,Java5又增長了Queue體系集合,表明一種隊列集合實現。安全
四、Java集合類主要由兩個接口派生出來:Collection和Map,Collection和Map是Java集合框架的根接口,以下圖所示是Collection接口、子接口及其實現類的繼承樹。數據結構
注:斜體字表明接口,正體的爲實現類。多線程
用藍框標註的類是Collection集合框架最經常使用的實現類,分別是:HashSet、TreeSet、ArrayList、LinkedList、ArrayDeque。框架
Set集合幾乎等同於Collection集合。它們的行爲幾乎一致。工具
遍歷Set的兩種方式:性能
1.用迭代器spa
2.用foreach循環線程
HashSet的存儲機制:
一、當有元素加進來的時,HashSet會調用該對象的hashCode()方法,獲得一個int值。
二、根據hashCode的()返回的int值,計算出它在HashSet中的存儲位置(底層實際採用數組存儲元素的索引,計算獲得在數組中的索引值)
三、若是加入的位置爲空,則直接加入,若是該位置已經有元素,則此處會造成鏈表。
取元素時與此相似。
一、當要去一個元素時,HashSet會調用該對象的hashCode()方法,獲得一個int值。
二、根據hashCode的()返回的int值,計算出它在HashSet的【底層數組】中的存儲位置(數組中的索引)。
三、若是該位置剛好是要找的元素,直接取出便可,如若是該位置由鏈表,則要經過」挨個「搜索鏈表中的元素。
HashSet存儲機制示意圖
HashSet的構造方法:HashSet(int initialCapacity, float loadFactor)
initialCapacity:控制底層數組的長度,默認爲16
loadFactor:負載因子,HashSet判斷是否【底層數組快滿】時的依據。當判斷認爲數組快滿時,系統會自動建立一個長度爲原來2倍的數組,而且將原來數組的元素複製到新數組,原來的數組成爲了垃圾。專業術語叫作」rehash(重hash)「。
loadFactor的默認大小爲0.75。
loadFactor越小,越消耗內存,loadFactor越大,性能越低。
hashSet怎樣判斷兩個對象是否相等:
一、兩個對象的hashCode()返回值相同
二、兩個對象的equals()方法比較返回值爲true
這就要求咱們自定義類的hashCode()和equals()方法是一致的,要求重寫equals()所用的關鍵屬性與計算hashCode()的關鍵屬性一致。
它與HashSet的存儲機制相同。
但LinkedHashSet額外維護一個鏈表,用來記錄元素的添加順序。
特徵:保證Set裏的元素是」有大小排序「的。
TreeSet————它是標準的紅黑樹
樹—>二叉樹—>排序二叉樹—>平衡二叉樹—>紅黑樹。
TreeSet的存儲機制:
底層由一棵」紅黑樹「存放全部的數據。存取性能與檢索性能也比較好。
在HashSet沒有出現大量的鏈表的狀況下,HashSet的性能要比TreeSet性能好。
TreeSet要求對象必須是能夠排序的:
一、天然排序。要求全部的集合元素實現Comparable接口。
集合元素實現了Comparable接口後,集合元素自身就能夠排序。
二、定製排序。要求建立TreeSet對象的時候傳入一個Comparator對象。
Comparator對象負責對集合元素進行排序,集合元素無需實現Comparable接口。
TreeSet怎樣纔算兩個對象時相等?
一、只有兩個對象經過compareTo()方法比較的返回值爲0,TreeSet才認爲兩個對象相等。
List集合封裝了線性表的數據結構。
它提供大量的」根據索引「來存、取元素的方法。
因爲List根據索引來存、取元素,所以它多了一個遍歷元素的方法。
ArrayList與Vector的存儲機制:
它們的底層是基於數組的,它們對元素的存儲徹底是基於數組的。 —— 所以性能很是快。
ArrayList與Vector的區別:
一、Vector是JDK1.0就有的集合,從JDK1.2之後SUN公司從新設計了ArrayList來代替Vector。
二、Vector是線程安全的,ArrayList是線程不安全的。但ArrayList的性能要比Vector的好。
即便在多線程的環境下,可使用Collections的方法把ArrayList變成線程安全的。
如下僅供瞭解
三、當底層數組的存儲空間不足時,Vector默認擴轉1倍,ArrayList默認擴展%50+1。
既是線性表,又是隊列,仍是棧。(棧和隊列是受限的線性表)。
LinkedList的底層是基於鏈表實現的。一般認爲它的性能比不上ArrayList。
ArrayList:因爲根據底層數組的索引存取元素的,因此性能很是快。
當插入、刪除元素時,後面全部的元素都要跟上」總體搬家「。
LinkedList:因爲底層採用鏈表來存儲元素,要根據遍從來存取元素,因此性能較低。
當插入、刪除元素時,後面全部的元素無需」總體搬家「,所以性能很是好。
雙向隊列:功能限制的線性表
即便隊列,又是棧。
看成棧是使用的方法是push()和pop(),peek()只訪問棧頂元素,並不彈出來。
看成隊列時使用的方法是offer()和poll()。
ArrayDeque —— 基於數組實現
LinkedList —— 基於鏈表實現
操做集合工具類:Collections
synchronizedXxx —— 把原有的集合包裝成線程安全的集合。
shuffle(List<?> list) —— 把List集合元素進行隨機排列
常見的工具類:
Arrays —— 操做數組。
Objects —— 操做對象。
Collections ——操做集合。
以下圖爲Map體系的繼承樹,全部的Map實現類用於保存具備映射關係的數據。Map保存的數據都是key-value對。
注:用藍框標註的類是Map集合框架最經常使用的實現類,分別是:HashMap、TreeMap、Properties。
對比以上兩圖,發現兩者的結構很是相識,Map與Set一一對應。實質上Set底層的實現就是經過Map子類的方法,能夠經過查看Set相關的API文檔驗證。當Map的value值爲null,只考慮key的時候,Map就變爲了Set。
HashSet底層是由HashMap實現,HashMap經過「hash」算法控制數據在集合中的存儲,相似於「一個蘿蔔一個坑」。
TreeSet底層是由TreeMap實現,TreeMap就是真正的紅黑樹。
注:對於Map而言,value只是它的附屬物,幾乎沒有什麼要求,所以Map主要是對key由要求。
HashMap會經過key的hashCode()方法的返回值來計算其存、取位置。
HashMap怎樣纔算兩個key重複呢?
一、經過equals()方法比較的返回值爲true
二、兩個key的hashCode()返回值相同
判斷兩個對象相等能夠用hashcode比較嗎?
回答是不能夠。你必須用equals方法!兩個不一樣對象可能hashcode相等,但兩個不一樣hashcode的對象必定不一樣。另一點,若是覆寫 了equals方法,必須覆寫hashcode方法,緣由是默認的hashcode是將對象的存儲地址進行映射。並且邏輯上,若是兩個對象的equals 方法返回是相等的,那麼它們的hashcode必須相等;反之不必定成立。
底層的紅黑樹只對key進行排序
TreeMap要求key必須是能夠排序的:
一、天然排序。要求全部的key實現Comparable接口。
二、定製排序。要求建立TreeMap對象的時候傳入一個Comparator接口的對象。
TreeMap怎樣纔算兩個key相等?
一、經過compareTo()方法比較的返回值爲0,這就代表兩個元素相等。
HashMap與HashTable的區別:
一、HashTable是從JDK1.0就有的,儘可能少用。
二、HashTable不容許null做爲key、value。但HashMap容許。
三、HashTable是線程安全的(實現的很差)
HashMap是線程不安全的。由於它不須要進行同步檢驗,因此性能好。
Map Collections.synchronizedMap(Map m)
這個方法返回一個同步的Map,這個Map封裝了底層的HashMap的全部方法,使得底層的HashMap即便是在多線程的環境中也是安全的。
如下幾條僅供瞭解:
四、HashTable中hash數組默認大小是11,增長的方式是 old*2+1。HashMap中hash數組的默認大小是16,並且必定是2的指數。
五、哈希值的使用不一樣,HashTable直接使用對象的hashCode, 而HashMap從新計算hash值。
六、.HashTable使用Enumeration,HashMap使用Iterator。
七、HashTable有一個contains(Object value),功能和containsValue(Object value)功能同樣。
八、.Hashtable是Dictionary的子類,HashMap是Map接口的一個實現類;