我的jdk源碼(十): AbstractSet Set家族的骨架實現類

一、概述

    AbstractSet類是Set家族中的骨架實現類,在接口與實現類之間構建了一層抽象,其目的是爲了複用一些比較通用的函數以及方便擴展,爲子類提供共用的方法模板。 AbstractSet類相比AbstractList和AbstractMap內容要少很多。

二、源碼分析

    (1) 類的聲明,源碼如下:

public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E>

    AbstractSet類, 提供一個Set實現的骨架,使得在實現Set接口時重複寫很多相同的代碼,Set作爲一個Colletion,也應該具有一些Colletion應該具有的性質(或者說限制)和操作,也不用自己來寫,直接繼承,也是爲了不重複寫代碼。

    (2) equeals()方法,源碼如下:

    public boolean equals(Object o) {
        //判斷是否本身
        if (o == this)
            return true;
        //判斷是否是Set類型,不是就直接返回false
        if (!(o instanceof Set))
            return false;
        //參數對象轉換成Collection
        Collection<?> c = (Collection<?>) o;
        //比較容量,不一致則返回false
        if (c.size() != size())
            return false;
        //以上都滿足,則比較內容
        try {
            //調用AbstractCollection類的containsAll()方法進行比較
            return containsAll(c);
        } catch (ClassCastException unused)   {
            return false;
        } catch (NullPointerException unused) {
            return false;
        }
    }

    AbstractSet類的equals()方法邏輯比較簡單,和AbstractMap類的equals()的邏輯類似,只是在比較內容的時候,AbstractSet類的equals()方法是直接調用的AbstractCollection類的containsAll()方法。

    (3) hashCode()方法,源碼如下:

    public int hashCode() {
        int h = 0;
        Iterator<E> i = iterator();
        while (i.hasNext()) {
            E obj = i.next();
            if (obj != null)
                h += obj.hashCode();
        }
        return h;
    }

     AbstractSet的hash值就是把所有的元素(對象)的hash值相加,保證了相同的Set必須相同的hash值,和AbstractMap類一致。

    (4) removeAll()方法,源碼如下:

    //從本Set中刪除參數包含的所有元素
    public boolean removeAll(Collection<?> c) {
        Objects.requireNonNull(c);
        //標記是否被修改
        boolean modified = false;

        if (size() > c.size()) {
            for (Iterator<?> i = c.iterator(); i.hasNext(); )
                //參數中的元素比較少,則參數中的所有元素調用remove進行查找,如果查找到並且刪除,則 modified變爲true
                modified |= remove(i.next());
        } else {
            for (Iterator<?> i = iterator(); i.hasNext(); ) {
                //Set中的元素比較少,迭代本Set的元素,看是否包含在參數的元素中,如果是,則remove
                if (c.contains(i.next())) {
                    i.remove();
                    modified = true;
                }
            }
        }
        return modified;
    }

三、總結

     AbstractSetl類方法比較少,具體還是要看它的子類。敬請期待《我的jdk源碼(十一):ArrayList類》。 更多精彩內容,請掃描下方二維碼,關注我的微信公衆號【Java覺淺】,第一時間獲取更新!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章