什麼是set
Set 具有與 Collection 完全一樣的接口 行為上不同 Set 不儲存重複的元素
分類
- HashSet:最主要的實作類 線程不安全 可以存儲null
- LinkedHashSet:作為HashSet子類 周遊内部資料時 可以按照添加的方式來顯示
- TreeSet:可以按照添加對象的指定屬性 進行排序
Set特點
- 無序:存儲的資料在底層中并非按照資料的索引 而是根據資料的哈希值來确定位置
- 不可重複:保證添加的元素按照equals判斷時 不能傳回true 即相同的元素隻能添加一個
- Set接口中沒有拓展Collection中的方法(
- 向Set接口中添加資料時 其所在的類一定要重寫 hashCode() 和 equals()方法 相等的對象必須擁有相等的散列碼
HashSet添加元素過程
向HashSet添加 元素 a 首先調用a所在類的hashCode()方法 計算a的哈希值
此哈希值通過HashSet内部某種算法計算出 a 在HashSet中的位置(即為 索引位置)
判斷此位置上是否有值
如果沒有 元素 a 添加成功 ==>情況1
如果存在元素 b(或者以連結清單存在的多個元素) 則比較元素 a 和 元素 b 的hash值
如果不相同 添加成功 ==>情況2
如果相同 調用元素 a 所在類的equals方法
equals傳回true 添加失敗
equals傳回false 添加成功 =>情況3
情況2和情況3 元素 a 和 已經存在指定索引位置的元素以連結清單的方式進行存儲
jdk8:原來的資料在數組中 指向元素 a
jdk7:a放到數組中 指向原來的資料
HashSet底層: 數組 + 連結清單
示例
HashSet
package com.collection;
import org.junit.Test;
import java.util.HashSet;
import java.util.Set;
/*
* Set接口
* 無序 不可重複
* 無序:存儲的資料在底層中并非按照資料的索引 而是根據資料的哈希值來确定位置
* 不可重複:保證添加的元素按照equals判斷時 不能傳回true 即相同的元素隻能添加一個
* Set接口中沒有拓展Collection中的方法
* */
public class Demo03 {
@Test
public void test(){
Set set = new HashSet();
set.add(111);
set.add(222);
set.add(333);
set.add(111);
set.add(new User("yyll",20));
set.add(new User("yyll",20));
System.out.println(set);
/*
* 輸出結果 [333, 222, 111]
* 不可重複
* */
}
}
TreeSet
package com.collection;
import org.junit.Test;
import java.util.TreeSet;
public class Demo04 {
@Test
public void test(){
TreeSet treeSet = new TreeSet();
treeSet.add(123);
treeSet.add(445);
treeSet.add(1323);
treeSet.add("bb");
/*
* java.lang.Integer cannot be cast to java.lang.String
*
* 不能添加不同類型的資料
* TreeSet
* */
}
}
小結
- Set接口
無序
不可重複
-
不能添加不同類型的資料 可以自定義排序規則TreeSet
即使再小的帆也能遠航