<<重新開機6>>
學習分享-jdk1.8各類集合的特點
三大集合:list,map.set的差別與聯系
特點
- list: 有序集合,元素可重複
- Set: 不重複集合,LinkedHashSet按照插入排序,SortedSet可排序,HashSet無序
- Map: 鍵值對集合,存儲鍵、值和之間的映射;Key無序,唯一;value 不要求有序,允許重複
差別
- list可以放多個null,set隻能放一個null,map隻能一個key值為null,可以有多個value為空
- 集合排序:list有序,set實作類可有序、可無序,map無序
- list通過下标按順序存儲,map通過鍵值對方式存儲
聯系
- List , Set, Map都是接口,前兩個繼承至Collection接口,Map為獨立接口
List
它的實作類有三個,分别為:ArrayList、Vector 和 LinkedList
類型 | 安全 | 類型 | 特點 | 擴容 | 初始容量 |
---|---|---|---|---|---|
ArrayList | 線程不安全 | 數組 | 查詢快、增删慢 | 1.5倍 | 10 |
LinkedList | 線程不安全 | 雙向連結清單 | 查詢慢、增删快 | 無 | 無 |
Vector | 線程安全 | 數組 | 查詢快、增删慢 | 2倍 | 10 |
ArrayList
ArrayList 是最常用的 List 實作類,内部是通過數組實作的,它允許對元素進行快速随機通路。數組的缺點是每個元素之間不能有間隔, 當數組大小不滿足時需要增加存儲能力,就要将已經有數組的資料複制到新的存儲空間中 。 當從 ArrayList 的中間位置插入或者删除元素時,需要對數組進行複制、移動、代價比較高。是以,它适合随機查找和周遊,不适合插入和删除 。
常用方法
import java.util.ArrayList;
public class F{
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
// 追加
list.add("1");
// 指定位置插入
list.add(1,"2");
list.add("3");
// toString方法
System.out.println(list.toString());
// contains方法,傳回true,false
System.out.println(list.contains("1"));
// get方法 ,根據index擷取元素
System.out.println(list.get(1));
// 傳回與指定值第一個比對的index
System.out.println(list.indexOf("1"));
// 根據value移除第一個值相同的元素
list.remove("1");
// 格局index移除元素
list.remove(0);
System.out.println(list.toString());
// 給指定index位置指派
list.set(0,"1");
System.out.println(list.toString());
}
}
Vector
Vector 與 ArrayList 一樣,也是通過數組實作的,不同的是 它支援線程的同步,即某一時刻隻有一個線程能夠使用 Vector ,避免多線程同時寫而引起的不一緻性,但實作同步需要很高的花費,是以,通路它比通路 ArrayList 慢。
Vector 和 ArrayList 實作了同一接口 List, 但所有的 Vector 的方法都具有 synchronized 關鍵字修飾。但對于複合操作,Vector 仍然需要進行同步處理。
LinkedList
LinkedList 是用連結清單結構存儲資料的,很适合資料的動态插入和删除 ,随機通路和周遊速度比較慢。另外,他還提供了 List 接口中沒有定義的方法,專門用于操作表頭和表尾元素,可以當作堆棧、隊列和雙向隊列使用。
Set
他的實作類也有三個,他們分别為:HashSet、LinkedHashSet和TreeSet
名稱 | 資料結構 | 線程安全 | 是否有序、唯一 | 允許null | 如何實作有序 | 如何實作唯一 |
---|---|---|---|---|---|---|
HashSet | 哈希表 | 不安全,不同步 | 無序、唯一 | 允許 | 無序 | hashcode()+equals() |
LinkedHashSet | 連結清單+哈希表 | 不安全 | 有序、唯一 | 允許 | 連結清單FIFO | 由哈希表保證元素唯一 |
TreeSet | 紅黑樹 | 不安全 | 有序、唯一 | 不允許 | 自然排序、比較器排序 | 根據比較的傳回值是否是0來決定 |
HashSet
哈希表邊存放的是哈希值。HashSet 存儲元素的順序并不是按照存入時的順序(與 List 顯然不同) 而是按照哈希值來存的是以取資料也是按照哈希值取得。
特點:
1、不允許存儲重複元素
2、沒有索引,沒有帶索引的方法,不能使用fori的方法周遊
3、是一個無序的集合,存儲元素和取出元素可能不一緻
4、底層是一個哈希表結構,查詢速度非常快
LinkHashSet(HashSet+LinkedHashMap)
LinkHashSet實作了Set接口,繼承了HashSet類,是有序的,與HashSet相比,他多了一個連結清單,用來記錄元素的存儲順序,保證元素有序。LinkHashSet是由HashSet和一個連結清單組成,HashSet本身就是由數組+連結清單可能還會有紅黑樹組成的,對于 LinkedHashSet 而言,它繼承與于HashSet、又基于 LinkedHashMap 來實作的。
TreeSet(二叉樹)
- TreeSet 類繼承了 Set 接口和 SortedSet 接口,元素不能重複
- 由于 SortedSet 接口能對元素升序排序,Integer 和 String 對象都可以進行預設的 TreeSet 排序,而自定義類的對象是不可以的,自己定義的類必須實作 Comparable 接口,并且覆寫相應的 compareTo()函數,才可以正常使用。
- 底層依賴于 TreeMap,元素沒有索引
- 存儲大量的需要進行快速檢索的排序資訊時,TreeSet 是一個很好的選擇
Map
名稱 | 線程安全 | 底層實作 | 效率 | null允許 | 有序 |
---|---|---|---|---|---|
HashMap | 不安全(不同步) | 數組+單連結清單(紅黑樹) | 高 | 可以允許一條記錄的鍵為 null,允許多條記錄的值為 null) | 無序 |
HashTable | 安全(synchronized修飾public方法,同步) | 哈希表 | 低 | 鍵和值都不允許null | 無序 |
LinkHashMap | 不安全 | HashMap+連結清單 | 高 | 有序 |
HashMap(數組+連結清單+紅黑樹)
HashMap 根據鍵的 hashCode 值存儲資料,大多數情況下可以直接定位到它的值,因而具有很快的通路速度,但周遊順序卻是不确定的。 HashMap 最多隻允許一條記錄的鍵為 null,允許多條記錄的值為 null。HashMap 非線程安全,即任一時刻可以有多個線程同時寫 HashMap,可能會導緻資料的不一緻。如果需要滿足線程安全,可以用 Collections 的 synchronizedMap 方法使HashMap 具有線程安全的能力,或者使ConcurrentHashMap。
同時,hashmap也是java面試八股文經典題目,四聯問:
hashmap的1.8和1.8之前的差別在哪?hashmap的底層實作原理,hashmap的put請求流程,hashmap如何實作高效的線程安全(這個連結僅供參考)?
HashTable(線程安全)
Hashtable 是遺留類,很多映射的常用功能與 HashMap 類似,不同的是它承自Dictionary 類,并且是線程安全的,任一時間隻有一個線程能寫 Hashtable,并發性不如 ConcurrentHashMap,因為 ConcurrentHashMap 引入了分段鎖。Hashtable 不建議在新代碼中使用,不需要線程安全的場合可以用 HashMap 替換,需要線程安全的場合可以用 ConcurrentHashMap 替換。
LinkHashMap(記錄插入順序)
LinkedHashMap 繼承了HashMap ,是 HashMap 的一個子類,儲存了記錄的插入順序, 具有可預知的疊代順序。
周遊方式:
鍵找值 的方法:
1、通過Map集合的getKeys()方法,傳回集合的所有鍵的集合keys
2、周遊集合keys中的所有key,使用疊代器或者增強for循環周遊
2、通過Map集合的get(key)方法,根據鍵傳回對應的值