一、HashSet 集合類
1、簡介
HashSet 集合底層采取哈希表存儲數據
底層是HashMap
不能使存取有序
JDK8之前的哈希表是數組和鏈表,頭插法
JDK8之后的哈希表是數組、鏈表和紅黑樹,尾插法
2、存儲元素
(1)如果要保證元素的唯一性,需要同時重寫對象中的 hashCode 方法和 equals 方法
因為Object類的hashCode方法是調用底層的C++代碼計算了一個隨機數
(2)hashCode方法計算哈希值,equals方法比較元素
當添加對象的時候, 會先調用對象的hashCode方法計算出一個應該存入的索引位置, 查看該位置上是否存在元素
不存在:直接存
存在:調用equals方法比較內容
false:存
true:不存
3、底層原理細節(JDK8及以后)
(1)哈希擾動
底層會先計算出原始哈希值,設為 h
計算 h ^ ( h >> 16 ) 作為新的哈希值
以減少哈希沖突
(2)取模運算
用最終的哈希值對底層數組長度取模,得到索引位置
初始數組長度為16
計算時,并不是直接 H % 16
而是?( 16 - 1 ) & H
對16取模相當于取后四位,和1111做與運算也是取后四位
與運算的效率高于取模運算
(3)數組擴容與樹化操作
擴容數組的條件:
當數組中的元素個數到達了 16 * 0.75 (加載因子) = 12,擴容到原數組 2 倍的大小
鏈表掛載的元素超過了8 (閾值) 個 , 并且數組長度沒有超過64
鏈表轉紅黑樹的條件:
鏈表掛載的元素超過了8 (閾值) 個, 并且數組長度到達了64
二、LinkedHashSet 集合類
1、簡介
存取有序、去重、無索引
2、原理
底層數據結構是依然哈希表,只是每個元素又額外的多了一個雙鏈表的機制記錄存儲的順序
三、幾種單列集合的選擇
1、元素可重復,用 ArrayList(最常用)
2、元素可重復,且增刪多于查詢,用LInkedList
3、元素不重復,用HashSet(最常用)
4、不重復且存取有序,用LinkedHashSet
5、想對元素排序,用TreeSet
四、可變參數
可變參數用在形參中可以接收多個數據
可變參數的格式:數據類型...參數名稱
傳輸參數非常靈活,方便,可以不傳輸參數,可以傳輸1個或者多個,也可以傳輸一個數組
可變參數在方法內部本質上就是一個數組
注意:一個形參列表中可變參數只能有一個,可變參數必須放在形參列表的最后面
public static void main(String[] args) {System.out.println(add(1)); // 1System.out.println(add(1,2,3)); // 6int[] arr = {1,2,3,4};System.out.println(add(arr)); // 10
}public static int add(int... nums) {int sum = 0;for (int num : nums) {sum += num;}return sum;
}
五、Collections 集合工具類
Collections并不屬于集合,是用來操作集合的工具類
public?static?<T>?boolean?addAll(Collection<??super?T>?c,?T...?elements) | |
public?static?void?shuffle(List<?>?list)? | |
public static <T> int binarySearch?(List<T> list, ?T key) | |
public static <T> void max/min(Collection<T> coll) | |
public static <T> void swap(List<?> list, int i, int j) | |
public static <T> void sort(List<T> list) | |
public static <T> void sort(List<T> list,Comparator<? super T> c) |
六、Map 接口
1、Map 集合
Map 集合是一種雙列集合,每個元素包含兩個數據
Map 集合的每個元素的格式:key = value(鍵值對元素)
key (鍵):不允許重復
value (值):允許重復
鍵和值是一一對應的,每個鍵只能找到自己對應的值
key + value 這個整體稱為“鍵值對”或者“鍵值對對象”,在Java中使用Entry對象表示
2、常用方法
Map是雙列集合的頂層接口,它的功能是全部雙列集合都可以繼承使用的
V?put(K?key,V?value) | |
V?remove(Object?key) | |
void?clear() | |
boolean?containsKey(Object?key) | |
boolean?containsValue(Object?value) | |
boolean?isEmpty() | |
int?size() |
3、特點
雙列集合底層的數據結構都是針對于鍵有效,和值無關
HashMap:鍵唯一(重寫hashCode方法和equals方法)
TreeMap:鍵排序(實現comparable接口并重寫compareTo方法)
LinkedHashMap:鍵唯一且存取有序
4、遍歷方式
(1)通過鍵找值
V?get(Object?key)? | |
Set<K>?keySet()? |
(2)通過鍵值對對象獲取鍵和值
Set<Map.Entry<K,V>>?entrySet()? |
(3)通過 forEach 方法遍歷
default?void?forEach? |