Java 集合類

爲何使用集合java

數組長度是固定,若是要改變數組的長度須要建立新的數組將舊數組裏面的元素拷貝過去,使用起來不方便。數組

java給開發者提供了一些集合類,可以存儲任意長度的對象,長度能夠隨着元素的增長而增長,隨着元素的減小而減小,使用起來方便一些。安全

 

數組和集合的區別網絡

區別1:數據結構

數組既能夠存儲基本數據類型,又能夠存儲引用數據類型,基本數據類型存儲的是值,引用數據類型存儲的是地址值。併發

集合只能存儲引用數據類型(對象),若是存儲基本數據類型時,會自動裝箱變成相應的包裝類。性能

區別2:spa

數組長度是固定的,不能自動增加線程

集合的長度的是可變的,能夠根據元素的增長而自動增加code

集合基礎體系圖


java提供了一些集合類,這些集合類分別適用於不一樣的場景,下面是經常使用的一些集合基礎體系圖(圖片引自網絡)。

Collection類圖

Collection是接口,下面的List、Set、Queue也都是接口,而且繼承了這個Collection。最下面的ArrayList、LinkedList、Vector、HashSet、TreeSet、PriorityQueue都是他們的實現類。

List:存放的數據是有順序的,能夠存放重複的數據。

LinkedList :基於鏈表實現,鏈表內存是散列的,增刪快,查找慢;  

ArrayList :基於數組實現,非線程安全,效率高,增刪慢,查找快;  

Vector :基於數組實現,效率低,增刪慢,查找慢,線程安全

Set:存放的數據是沒有順序的,不能存放重複的數據;

TreeSet:提供有序的Set集合,是天然排序,它繼承了AbstractSet抽象類,相對讀取慢;

HashSet :底層是由 Hash Map 實現,不容許集合有重複的值,使用該方式時須要重寫 equals()和 hashCode()方法; 

LinkedHashSet :繼承於 HashSet,同時又基於 LinkedHashMap 來進行實現,底層使用的是 LinkedHashMap,按添加順序排序;

Queue:是一個隊列,裏面的數據是先進先出,能夠存放重複的數據。

 

Collections是針對集合類的一個幫助類。提供了一系列靜態方法實現對各類集合的搜索排序線程徹底化等操做。 
 例如:

Collections.max(Collection coll);  取coll中最大的元素。 
Collections.sort(List list);  對list中元素排序

Map是接口,下面的HashMap、HashTable、AbstractMap也都是接口,而且繼承了這個Map。最下面的LinkedHashMap、TreeMap是他們的實現類。

HashMap裏面存放的數據是沒有順序的,鍵值對能夠存null鍵和null值,key 不能重複,值可重複,線程不安全。

LinkedHashMap :繼承 了HashMap ,保存了記錄的插入順序; 

HashTable裏面存放的元素不保證有序,key 不能重複,值可重複,線程安全

TreeMap:基於紅黑樹 (red-black tree) 數據結構實現,按 key 排序,默認的排序方式是升序。

 

 

HashMap詳情分析

HashMap其實是一個「鏈表散列」的數據結構,即數組和鏈表的結合體。

HashMap的底層結構是一個數組,數組中的每一項是一條鏈表。

HashMap的實例有兩個參數影響其性能「初始容量」 和 裝填因子。

HashMap實現不一樣步,線程不安全,HashTable線程安全。

HashMap中的key-value都是存儲在Entry中的。

HashMap能夠存null鍵和null值,不保證元素的順序恆久不變,經過hashCode()方法和equals方法保證鍵的惟一性。

hashCode()方法解決哈希衝突主要有三種方法:開放定址法,鏈表法,再散列法

HashMap是採用 鏈表法 解決哈希衝突的。

注: 鏈表法是將相同hash值的對象組成一個鏈表放在hash值對應的槽位;    

 

Hashtable、HashMap、ConcurrentHashMap的區別

HashMap和HashTable在功能上基本相同,但HashMap是線程不安全的,HashTable是線程安全的;

HashMap的key和value都是能夠爲null的,當get()方法返回null值時,HashMap中可能存在某個key,只不過該key值對應的value爲null,也有多是HashMap中不存在該key,因此不能使用get()==null來判斷是否存在某個key值,對HashMap和HashTable,提供了containsKey()方法來判斷是否存在某個key。

HashTable是不容許key和value爲null的。HashTable中的方法大部分是同步的,所以HashTable是線程安全的。

在JDK1.5之後,出現了ConcurrentHashMap和HashTable功能很像,不容許爲null的key或value,但它不是經過給方法加synchronized方法進行併發控制的。在ConcurrentHashMap中使用分段鎖技術Segment,將數據分紅一段一段的存儲,而後給每一段數據配一把鎖,當一個線程佔用鎖訪問其中一個段數據的時候,其餘段的數據也能被其餘線程訪問,可以實現真正的併發訪問。效率也比HashTable好的多。

 

TreeMap、HashMap、LinkedHashMap的區別

LinkedHashMap保存了數據的插入順序,底層是經過一個雙鏈表的數據結構來維持這個插入順序的,key和value均可覺得null。

TreeMap實現了SortMap接口,它保存的記錄是根據鍵值key排序,默認是按key升序排列。也能夠指定排序的Comparator。

 

HashMap、LinkedHashMap和TreeMap都是線程不安全的,提供兩種遍歷Map的方法以下
推薦方式

Map<String, Integer> map = new HashMap<String, Integer>(20); //直接遍歷出Entry  for(Map.Entry<String, Integer> entry : map.entrySet()){ System.out.println("key-->"+entry.getKey()+",value-->"+m.get(entry.getValue())); }

這種方式至關於首先經過Set<Map.Entry<String,Integer>> set =  map.entrySet();方式拿到Set集合,而Set集合是能夠經過foreach的方式遍歷的。

普通方式

Map<String, Integer> map = new HashMap<String, Integer>(20); Iterator<String> keySet = map.keySet().iterator(); //遍歷Hash表中的key值集合,經過key獲取value  while(keySet .hasNext()){ Object key = keySet .next(); System.out.println("key-->"+key+",value-->"+m.get(key)); }

HashSet內部使用Map保存數據,即將HashSet的數據做爲Map的key值保存,這也是HashSet中元素不能重複的緣由。而Map中保存key值的,會去判斷當前Map中是否含有該Key對象,內部是先經過key的hashCode,肯定有相同的hashCode以後,再經過equals方法判斷是否相同。

相關文章
相關標籤/搜索