【java】【集合】set集合、唯一性保證、Linkset、案例
一、set概述
1、通過API檢視即可:方法和collection中的方法一模一樣,沒什麼特別的方法,主要學習set的子類如何保證元素的唯一性。
2、 特點:
- 無索引:不可以通過索引值去操作集合
- 不可以重複:add()新增時,如果發現值重複了就會返回false,表示儲存不成功
- 無序(存取不一致)
3、遍歷:不能使用索引值遍歷,但是可以用迭代器遍歷(迭代器或增強for迴圈)
public static void demo1() {
HashSet<String> hs = new HashSet<>(); //建立HashSet物件
boolean b1 = hs.add("a");
boolean b2 = hs.add("a"); //當向set集合中儲存重複元素的時候返回為false
hs.add("b");
hs.add("c");
hs.add("d");
System.out.println(hs); //HashSet的繼承體系中有重寫toString方法
System.out.println(b1);
System.out.println(b2);
for (String string : hs) { //只要能用迭代器迭代的,就可以使用增強for迴圈遍歷
System.out.println(string);
}
}
二、HashSet原理
1、原理
- 我們使用Set集合都是需要去掉重複元素的,如果在儲存的時候逐個equals()比較,效率較低:可以先判斷hashcode值,如果相同再去呼叫equals比較。雜湊演算法提高了去重複的效率, 降低了使用equals()方法的次數
- 當HashSet呼叫add()方法儲存物件的時候,先呼叫物件的hashCode()方法得到一個雜湊值, 然後在集合中查詢是否有雜湊值相同的物件:(只有hashcode值相同的時候才去呼叫equals方法)
- 如果沒有雜湊值相同的物件就直接存入集合
- 如果有雜湊值相同的物件,就和雜湊值相同的物件逐個進行equals()比較,比較結果為false就存入,true則不存
2、將自定義類的物件存入HashSet去重複
- 類中必須自己重寫hashCode()和equals()方法:(為了保證set中元素的唯一性),如果不重寫equals方法,equals方法是按照物件的地址值比較,new物件的地址值都不同,因此可能會將相同物件當做不同物件進行儲存,無法保證元素的唯一性
- hashCode():屬性相同的物件返回值必須相同, 屬性不同的返回值儘量不同(提高效率,降低使用equals方法的次數)
- equals():屬性相同返回true, 屬性不同返回false,返回false的時候儲存
注意:若不是自定義物件,java會自動重寫hashcode和equals方法來保證set集合元素的唯一性
下面是Person物件傳入set集合時java自動重寫:
/*
* 為什麼是31?
* 1,31是一個質數,質數是能被1和自己本身整除的數
* 2,31這個數既不大也不小
* 3,31這個數好算,2的五次方-1,2向左移動5位
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) //呼叫的物件和傳入的物件是同一個物件
return true; //直接返回true
if (obj == null) //傳入的物件為null
return false; //返回false
if (getClass() != obj.getClass()) //判斷兩個物件對應的位元組碼檔案是否是同一個位元組碼
return false; //如果不是直接返回false
Person other = (Person) obj; //向下轉型
if (age != other.age) //呼叫物件的年齡不等於傳入物件的年齡
return false; //返回false
if (name == null) { //呼叫物件的姓名為null
if (other.name != null) //傳入物件的姓名不為null
return false; //返回false
} else if (!name.equals(other.name)) //呼叫物件的姓名不等於傳入物件的姓名
return false; //返回false
return true; //返回true
}
三、LinkedHashSet
- 底層是連結串列實現的,是set集合中唯一一個能保證怎麼存就怎麼取的集合物件,即按照順序去存和取
- 因為是hashset的子類所以也是保證元素唯一的,與hashset的原理一樣
四、案例練習
1、編寫一個程式,獲取10個1至20的隨機數,要求隨機數不能重複。並把最終的隨機數輸出到控制檯。
HashSet<Integer> hs = new HashSet<>(); //建立集合物件
Random r = new Random(); //建立隨機數物件
while(hs.size() < 10) {
int num = r.nextInt(20) + 1; //生成1到20的隨機數
hs.add(num);
}
for (Integer integer : hs) { //遍歷集合
System.out.println(integer); //列印每一個元素
}
2、使用Scanner從鍵盤讀取一行輸入,去掉其中重複字元, 列印出不同的那些字元
Scanner sc = new Scanner(System.in); //建立鍵盤錄入物件
System.out.println("請輸入一行字串:");
String line = sc.nextLine(); //將鍵盤錄入的字串儲存在line中
char[] arr = line.toCharArray(); //將字串轉換成字元陣列
HashSet<Character> hs = new HashSet<>(); //建立HashSet集合物件
for(char c : arr) { //遍歷字元陣列
hs.add(c); //將字元陣列中的字元新增到集合中
}
for (Character ch : hs) { //遍歷集合
System.out.println(ch);
}
3、將集合中的重複元素去掉
分析:
- 建立List集合儲存若干個重複元素
- 單獨定義方法去除重複
- 分析:
* 去除List集合中的重複元素
* 1,建立一個LinkedHashSet集合
* 2,將List集合中所有的元素新增到LinkedHashSet集合
* 3,將list集合中的元素清除
* 4,將LinkedHashSet集合中的元素新增回List集合中 - 列印一下List集合
public static void main(String[] args) {
//1,建立List集合儲存若干個重複元素
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("a");
list.add("a");
list.add("b");
list.add("b");
list.add("b");
list.add("c");
list.add("c");
list.add("c");
list.add("c");
//2,單獨定義方法去除重複
getSingle(list);
//3,列印一下List集合
System.out.println(list);
}
public static void getSingle(List<String> list) {
//1,建立一個LinkedHashSet集合
LinkedHashSet<String> lhs = new LinkedHashSet<>();
//2,將List集合中所有的元素新增到LinkedHashSet集合
lhs.addAll(list);
//3,將list集合中的元素清除
list.clear();
//4,將LinkedHashSet集合中的元素新增回List集合中
list.addAll(lhs);
}
相關文章
- Java Set 常用集合 HashSet、LinkedHashSet、TreeSetJava
- Python set(集合)Python
- Hash Map集合和Hash Set集合
- python-集合setPython
- Java集合中List,Set以及Map等集合體系詳解(史上最全)Java
- Java 中的泛型 集合(List,Set) MapJava泛型
- Java內功心法,Set集合的詳解Java
- JAVA集合:常見Set原始碼學習Java原始碼
- List集合(ArrayList-LinkedList);Set集合(HashSet-TreeSet)
- Set集合類_演練
- python 集合型別 setPython型別
- for...of 迴圈, Set (集合)
- Java集合體系總結 Set、List、Map、QueueJava
- Python&Redis 無序集合set、有序集合zset操作PythonRedis
- 【Java集合】1 集合概述Java
- Python學習之set集合Python
- Java執行緒安全的集合類:Map、List、SetJava執行緒
- Java集合 Collection、Set、Map、泛型 簡要筆記Java泛型筆記
- 【JAVA集合】JAVA集合框架及其常用方法Java框架
- 【Java集合原始碼剖析】Java集合框架Java原始碼框架
- java集合Java
- Set集合的直接子類TreeSet
- 4、Set集合——HashSet、TreeSet(Comparable、Comparator)
- js資料結構--集合(set)JS資料結構
- Java集合詳解(一):全面理解Java集合Java
- Set集合的具體子類:HashSet
- 六,Java集合Java
- java集合框架Java框架
- java集合概述Java
- Java集合:HashMapJavaHashMap
- JAVA_集合Java
- java集合-ListJava
- Java集合-CollectionJava
- Java 集合框架Java框架
- Java集合大全Java
- Java 集合概述Java
- 集合類【Java】Java
- Java集合——ArrayListJava