標籤:set 集合 方法 元素
相關定義
作為Collection介面的重要子介面,Set介面是一個不包含重複元素,且元素排列無序的集合,也被稱為集。
注意:不包含重複元素的含義,更確切的講,set 不包含滿足 e1.equals(e2) 的元素對 e1 和 e2,並且最多包含一個 null 元素。
Set介面的方法和Collection介面的方法大體相同,也就是說Set介面不像List介面那樣可以通過索引或去元素,只能通過Iterator()方法擷取迭代器進行迭代。
Set中的add方法不同於Collection介面,有一個boolean類型的傳回值,當集合中含有與某個元素equals相等的元素時返回false,無法添加,否則返回true。
Set中的Iterator方法返回的返回的元素沒有特定的順序(除非此 set 是某個提供順序保證的類的執行個體)。
HashSet
HashSet類是Set介面的重要實作類別,由雜湊表(實際上是一個 HashMap 執行個體)支援。它不保證 set 的迭代順序;特別是它不保證該順序恒久不變。此類允許使用 null 元素。
此類為基本操作提供了穩定效能,這些基本操作包括 add、remove、contains 和 size,假定雜湊函數將這些元素正確地分布在桶中。對此 set 進行迭代所需的時間與 HashSet 執行個體的大小(元素的數量)和底層 HashMap 執行個體(桶的數量)的“容量”的和成比例。因此,如果迭代效能很重要,則不要將初始容量設定得太高(或將載入因子設定得太低)。
注意,此實現不是同步的。
另外,Set介面是通過equals方法來比較兩元素是否相同的,但是如果有1000個元素,那麼再添加一個元素,就要比較1000次,效率嚴重降低。所以HashSet類底層採用了HashMap來儲存元素,而HashMap採用了雜湊表的原理。
因此HashSet類按照雜湊演算法來存取對象,當向集合中加入一個新對象時,會調用對象的HashCode()方法得到對象的雜湊碼,然後根據這個碼計算出對象在集合中儲存的位置。 HashCode()方法實際上是返回的Object Storage Service的物理地址。
所以總的來說,HashSet是通過兩元素的HashCode()方法和equals()方法來判斷兩元素是否相等的。
所以當我們使用HashSet添加元素時一定要重寫該元素的HashCode方法和equals方法。並且,參與計算兩個方法傳回值的關鍵屬性應該相同。
例子:
import java.util.HashSet;import java.util.Iterator;import java.util.Set;public class SetText { public static void main(String[] args) { // TODO Auto-generated method stub Set<Person> set = new HashSet<>(); set.add(new SetText().new Person("sjs")); set.add(new SetText().new Person("sja")); Iterator<Person> iterator = set.iterator(); while(iterator.hasNext()){ System.out.println(iterator.next()); } } class Person{ private String name; public Person(String name) { this.name = name; } public String getName() { return name; } @Override public int hashCode() { return name.hashCode(); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (Person.class == obj.getClass()) { Person p = (Person)obj; return this.name.equals(p.getName()); } return false; } @Override public String toString() { return this.name; } }}
運行結果:
sjs
sja
重點掌握HashCode和equals方法的重寫辦法。
Java基礎之集合架構詳解(三)Set篇