1. 程式人生 > >java.util.Set學習筆記

java.util.Set學習筆記

概述

Set的概念與其在數學上的意義相同,是一種不允許存在重複元素的特殊集合,即:在一個Set中不包含滿足條件e1.equals(e2)的元素對e1e2。Set介面在從Collection中繼承的介面的基礎上,增加了額外的限制條件,主要包括的方法為:構造方法,add方法,equal方法和hashcode方法。為了描述的方便,在Set介面中宣告的方法包含了由Collection中繼承的介面。

構造方法的限制條件為:所有的構造方法必須構造一個不包含重複元素的集合。
注意:需要特別注意包含易變物件的集合。因為,Set介面中,沒有定義當其中的一個元素在改變過程與集合中另一個元素相等時的處理策略。因此出於這種考慮,集合是不能將自身作為一個元素新增到自身中的。對於這種情況,編寫如下測試類:


import java.util.HashSet;
import java.util.Set;

public class EqualClass {
    private int id;

    public EqualClass(int id) {
        this.id = id;
    }

    @Override
    public int hashCode() {
        return 1;
    }

    public int getId() {
        return id;
    }

    public void setId
(int id) { this.id = id; } @Override public boolean equals(Object obj) { if (obj == null || !(obj instanceof EqualClass)) { return false; } EqualClass o = (EqualClass) obj; return this.id == o.id; } @Override public String toString
() { return "id " + this.id; } public static final void main(String[] args) { Set<EqualClass> set = new HashSet<EqualClass>(); EqualClass class1 = new EqualClass(1); EqualClass class2 = new EqualClass(2); EqualClass class3 = new EqualClass(1); set.add(class1); set.add(class2); set.add(class3); System.out.println(class1.equals(class2)); System.out.println(set); class2.setId(1); System.out.println(class1.equals(class2)); System.out.println(set); } }

輸出結果如下:

false
[id 2, id 1]
true
[id 1, id 1]

由此可以看出,在開始時,由於class3與class1相等,因此,在新增到集合中時,並不會出現重複元素。而在class2在新增入集合後,發生修改,與class1相等,但是集合中並沒有排除重複元素,因此可能導致集合以後不可預期的行為,在編碼中應當特殊注意這種類似的情況發生。

一些Set介面的實現對於其中包含的元素有嚴格的限制。例如:有些實現不允許null元素,有些對元素的型別有限制。當試圖向集合中新增一個不滿足條件的元素時,則會丟擲一個非檢查(unchecked)異常,一般為:NullPointerException或者ClassCastException。當試圖檢索一個非法元素時,由兩種處理方式:丟擲異常,返回false。

方法介紹

在本文中,將針對一些與Collection中不同的介面進行介紹,其通用介面的介紹參見:java.util.Collection學習筆記

Iterator<E> iterator();

返回一個基於Set中元素的迭代器。與列表中的迭代器不同,Set迭代器放回元素的順序是不定的(除非集合的實現中提供了對於結合元素返回順序的支援)。

boolean add(E e);

將元素e新增到集合中。如果集合中已經包含與此元素相等的元素,則該操作不會對集合產生任何的修改,並返回false。與Set實現類提供的構造方法相結合,可以在一定程度上保證集合中不包含重複的元素。但是以上的這些額外限制並不意味著集合會接收所有的元素。Set可能拒絕一些特殊元素(如null),並丟擲一個異常。當自己在實現Set介面時,需要明確說明其中可以包含的元素的限制條件。

boolean addAll(Collection<? extends E> c);

將集合c中所有元素新增到指定Set中。在新增過程中,需要進行排重操作。如果c也是一個Set,那麼addAll操作即是數學中的並集操作。但是在執行本方法的過程中,如果c中的元素髮生改變,將產生不可預期的操作結果。

boolean retainAll(Collection<?> c);

在Set中僅保留c中包含的元素,將Set中的其它元素刪除。如果c也是一個Set,則本方法的操作結果相當於二者取交集。

boolean removeAll(Collection<?> c);

從Set中刪除集合c中的所有元素。如果c也是一個Set,則本方法的操作結果相當於數學中的差集操作。

boolean equals(Object o);

判斷Set與物件o是否相等。當o也是一個Set,並且與Set包含相同的元素時,返回true,否則返回false;這個方法保證了不同Set介面實現類之間進行等價比較時的正確性。

int hashCode();

計算當前Set的hash code。一個Set的雜湊值是當前集合中包含的所有元素的雜湊值的和(其中null元素的雜湊值被定義為0)。這保證了對於任意兩個集合s1和s2,當s1.equals(s2)時有s1.hashCode()==s2.hashCode()