Set 集合
java.util.Set 接口 extends Collection 接口
Set 接口的特點:
(1)不允許存儲重複的元素
(2)沒有索引,沒有帶索引的方法,也不能使用普通的for循環遍歷
java.util.HashSet 集合 implements Set接口
HashSet 接口的特點:
(3)是一個無序集合,存儲元素和取出元素的順序可能不一致
(4)底層是一個哈希表結構,特點是 「 查詢速度快 」
哈希值是一個十進位的整數,由系統隨機給出
(就是對象的地址值,是一個邏輯地址,是模擬出來得到的地址,不是數據實際存儲的物理地址)
在Object類有一個方法可以獲取對象的Hash值:int hashCode() ; --- 該方法返回調用這個方法的對象的哈希碼值
hasCode方法的源碼: public native int hashCode() ;
native:代表該方法調用的是本地作業系統的方法
public class Person extends Object {
}
public class DemoHahCode {
public static void main(String[] args) {
// Person類繼承了Object類,所以可以使用Object類的hashCode方法
Person p1 = new Person() ;
int h1 = p1.hashCode();
System.out.println(h1);
Person p2 = new Person() ;
int h2 = p2.hashCode();
System.out.println(h2);
}
HashSet集合存儲數據的結構 --- 哈希表(哈希表的特點:速度快)
jdk1.8版本之前 :哈希表 = 數組+鍊表
jdk1.8版本之後 :哈希表 = 數組+鍊表
哈希表 = 數組+紅黑樹(提高查詢速度)
【 什麼時候用紅黑樹呢?如果鍊表的長度超過了8位,則會把鍊表轉換為紅黑樹以提高查詢速度 】
數組結構:把元素進行分組(相同哈希值的元素一組)
鍊表 / 紅黑樹結構:把相同哈希值的元素連接到一起
Set集合存儲元素不重複的原理
前提:存儲的元素必須重寫hashCode方法和equals方法
具體說明:
Set集合在調用add方法的時候,add方法會調用元素的hashCode方法和equals方法,判斷元素是否重複
---> add方法會調用s1的hashCode方法,計算字符串「abc」的哈希值,哈希值是96354,在集合中找有沒有96354這個哈希值的元素,發現沒有,就會把s1存儲到集合中。
---> add方法會調用s2的hashCode方法計算字符串「abc」的哈希值,哈希值是96354,在集合中找有沒有96354這個哈希值的元素,發現有(哈希衝突),則s2會調用equals方法和哈希值相同的元素進行比較,s2.equals(s1)返回true,兩個元素的哈希值相同,equals方法返回true則說明兩個元素相同,這樣就不會把s2存儲到集合中。
---> add方法會調用「重地」的hashCode方法計算字符串的哈希值,哈希值是1179395,在集合中找有沒有1179395這個哈希值的元素,發現沒有,就會把「重地」存儲到集合中。
---> add方法會調用「通話」的hashCode方法計算字符串的哈希值,哈希值是1179395,在集合中找有沒有1179395這個哈希值的元素,發現有(哈希衝突),「通話」會調用equals方法和哈希值相同的元素進行比較,「通話」.equals(「重地」)返回false,兩個元素的哈希值相同,equals方法返回false則說明兩個元素不同,就會把「通話」存儲到集合中。
HashSet 存儲自定義類型元素
set集合報錯元素唯一:存儲的元素(String,Integer,...,Student,Person,...)必須重寫hashCode方法和equals方法
要求:同名同年齡的人視為同一個人,只能存儲一次
LinkedHashSet 集合
java.util.LinkedHashSet集合 extends HashSet集合
LinkedHashSet集合特點:底層是一個哈希表(數組+鍊表/紅黑樹)+鍊表 ----- 多了一條鍊表(記錄元素的存儲順序,保證元素有序)
可變參數
可變參數是 jdk1.5 之後出現的新特性
可變參數使用前提:當方法的參數列表數據類型已經確定,但是參數的個數不確定就可以使用可變參數
使用格式:定義方法時使用
修飾符 返回值類型 方法名(數據類型...變量名){ }
可變參數的原理:可變參數的底層就是一個數組,根據傳遞參數個數不同,會創建不同長度的數組,來存儲這些參數,傳遞的參數的個數可以是 0個(不傳遞)、1、2、...、多個
可變參數的注意事項:
(1)一個方法的參數列表只能有一個可變參數
(2)如果方法的參數有多個,那麼可變參數必須寫在參數列表的末尾