Java基础教程——Set
Set·無序,不重復(fù)
HashSet
特點:沒有重復(fù)數(shù)據(jù),數(shù)據(jù)不按存入的順序輸出。
HashSet由Hash表結(jié)構(gòu)支持。不支持set的迭代順序,不保證順序。
但是Hash表結(jié)構(gòu)查詢速度很快。
創(chuàng)建集合使用代碼:
Set<String> s = new HashSet<>();代碼演示:常用方法和遍歷輸出
import java.util.*; public class TestHashSet {public static void main(String[] args) {m010賦值A(chǔ)nd遍歷();}public static void m010賦值A(chǔ)nd遍歷() {System.out.println("=====賦值A(chǔ)nd遍歷");Set<String> s = new HashSet<>();s.add("孫悟空");s.add("小白龍");s.add("豬八戒");s.add("沙悟凈");s.add("孫悟空");System.out.println("是否為空:" + s.isEmpty());System.out.println("是否包含:" + s.contains("小白龍"));System.out.println("移除:" + s.remove("小白龍"));// (1)foreach:遍歷setfor (String str : s) {System.out.println(str);}// (2)迭代器:遍歷setIterator<String> it = s.iterator();while (it.hasNext()) {String str = it.next();System.out.println("Iterator : " + str);}// (3)*Java 8新增遍歷方法s.forEach(elm -> System.out.println("Lambda:" + elm));} }Hash和Hash表
Hash
HashCode,是一個十進制整數(shù),是對象的地址值(邏輯地址,不是物理地址)
Object類有一個方法,可以獲取對象的Hash值。
String重寫了hashCode方法
public int hashCode() {int h = hash;if (h == 0 && value.length > 0) {char val[] = value;for (int i = 0; i < value.length; i++) {h = 31 * h + val[i];}hash = h;}return h;}以至于有些不同字符串的hashCode相等(字符串還是不等的,無論==還是equals):
System.out.println("重地".hashCode());System.out.println("通話".hashCode());System.out.println("--------------");System.out.println("方面".hashCode());System.out.println("樹人".hashCode());System.out.println("--------------");System.out.println("兒女".hashCode());System.out.println("農(nóng)豐".hashCode());System.out.println("--------------");System.out.println("Ea".hashCode());System.out.println("FB".hashCode());Hash表
Java8之前:Hash表使用數(shù)組+鏈表;
Java8之后加入了紅黑樹,查詢速度加快。
Hash表結(jié)構(gòu)的示意圖如下所示:
數(shù)組里存儲的是HashCode。
HashCode相同的元素加入相同鏈表;
如果鏈表長度超過8,就轉(zhuǎn)為紅黑樹以提高查詢速度。
怎么才算重復(fù)?
HashSet中,元素不重復(fù)指“equals方法比較為true,且hashCode不同”。
下列示例代碼中,只有equals為true、且hashCode相同的對象未重復(fù)存入Set中。
import java.util.*; class A_equalsT {public boolean equals(Object obj) {return true;} } class B_hash1 {public int hashCode() {return 1;} } class C_hash2_equalsT {public int hashCode() {return 2;}public boolean equals(Object obj) {return true;} } public class TestSet怎么才算重復(fù) {public static void main(String[] args) {Set<Object> _set = new HashSet<Object>();_set.add(new A_equalsT());_set.add(new A_equalsT());_set.add(new B_hash1());_set.add(new B_hash1());_set.add(new C_hash2_equalsT());_set.add(new C_hash2_equalsT());for (Object object : _set) {System.out.println(object);}} }運行結(jié)果:(C_hash2_equalsT只存入一份,說明被看作重復(fù)對象)
B_hash1@1 B_hash1@1 C_hash2_equalsT@2 A_equalsT@15db9742 A_equalsT@6d06d69cHashSet存儲自定義元素時,需要重寫hashCode和equals方法,才能保證集合中對象的唯一性。
練習(xí):
創(chuàng)建Student類,至少需要包含id、name。創(chuàng)建多個Student對象加入HashSet,如果學(xué)號(id)相同則不重復(fù)加入。
TreeSet
TreeSet支持兩種排序方式,自然排序和定制排序。默認為自然排序,和HashSet的輸出順序不一樣。
TreeSet使用紅黑樹存儲元素(示例和下一小節(jié)一起)。
LinkedHashSet
Set也可以有序,這個LinkedHashSet就能按照輸入順序輸出結(jié)果。
LinkedHashSet也是根據(jù)元素的hashCode值決定元素的存儲位置,但是加了一條鏈表記錄元素的存儲順序,這使得元素有序。
import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Set; import java.util.TreeSet; public class TestTree{public static void main(String[] args) {m020各種Set();}private static void m020各種Set() {System.out.println("|-HashSet:");Set<String> _set;_set = new HashSet<String>();_set.add("B");_set.add("A");_set.add("1");_set.add("2");_set.add(null);printSet(_set);System.out.println("|-TreeSet不接受空值:");_set = new TreeSet<String>();_set.add("B");_set.add("A");_set.add("1");_set.add("2");// _set.add(null);printSet(_set);System.out.println("|-LinkedHashSet:有序");_set = new LinkedHashSet<String>();_set.add("B");_set.add("A");_set.add("1");_set.add("2");_set.add(null);printSet(_set);}private static void printSet(Set<String> _set) {for (String str : _set) {System.out.print(str + " ");}System.out.println();} }|-HashSet:
null A 1 B 2
|-TreeSet不接受空值:
1 2 A B
|-LinkedHashSet:有序
B A 1 2 null
Set的性能
HashSet綜合效率最高,LinkedHashSet因為有鏈表,遍歷時會更快一些。TreeSet因為要維護紅黑樹,效率較低。
轉(zhuǎn)載于:https://www.cnblogs.com/tigerlion/p/11179209.html
總結(jié)
以上是生活随笔為你收集整理的Java基础教程——Set的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 转再次写给我们这些浮躁的程序员
- 下一篇: Java集合框架体系(超详细)