1. 程式人生 > >Java基礎之有容乃大篇(AbstractSet)

Java基礎之有容乃大篇(AbstractSet)

AbstractSet

  它繼承了AbstractCollection,實現了Set介面,先回顧一下Set介面,Set介面繼承了Collection並沒有進行擴充套件,AbstractCollection實現了Collection介面部分方法。AbstractSet除了繼承自AbstractCollection的方法之外,都實現了哪些方法呢?

    原始碼之中AbstractSet程式碼很少,實現了removeAll方法,重寫了equals和HashCode方法。

    實現的removeAll方法

    public boolean removeAll(Collection<?> c) {
        Objects.requireNonNull(c);    //下次再遇到要判斷物件是否為空,空的時候報空指標異常的時候就可以使用這個方法。
        boolean modified = false;

        if (size() > c.size()) {    //如果當前Set的元素數量大於指定集合
            for (Iterator<?> i = c.iterator(); i.hasNext(); )//迭代指定集合中的元素全部移除
                modified |= remove(i.next());
        } else {
            for (Iterator<?> i = iterator(); i.hasNext(); ) {//小於指定集合就遍歷當前的Set
                if (c.contains(i.next())) {        //在指定集合c中看是否包含當前元素
                    i.remove();            //包含就移除
                    modified = true;
                }
            }
        }
        return modified;
    }

    重寫的equals和hashCode方法原始碼實現:

    public boolean equals(Object o) {
        if (o == this)            //同一物件返回true
            return true;

        if (!(o instanceof Set))//不是Set返回false
            return false;
        Collection<?> c = (Collection<?>) o;
        if (c.size() != size())    //大小不一樣返回false
            return false;
        try {
            return containsAll(c);    //當前集合是否包含待比較的物件集合,包含就返回ture不包含就返回false
        } catch (ClassCastException unused)   {
            return false;
        } catch (NullPointerException unused) {
            return false;
        }
    }
    public int hashCode() {
        int h = 0;                    //它的hashCode演算法是把所有的元素的hashCode值相加 返回
        Iterator<E> i = iterator();
        while (i.hasNext()) {
            E obj = i.next();        
            if (obj != null)
                h += obj.hashCode();
        }
        return h;
    }                                    //具體為什麼重寫equals就要重寫HashCode,在寫AbstractList那篇文章中有講
                                        //這裡再次提一嘴:  原因有二,
                                            1.如果我們使用的集合需要用到hash演算法,那就必須重寫
                                            2.Java規範的約定是,在集合類中使用自定義型別需要重寫這兩個方法。
                                        //這裡有大神部落格的連結:
https://blog.csdn.net/world6/article/details/70053356
                                        //部落格敘述的是HashMap的一些知識梳理和值得注意的點,其中有為什麼重寫這兩個方法的原因,還不錯

    Objects.requireNonNull方法解讀:

        這個方法是Objects類中的方法,原始碼如下,當引數object為空的時候,會丟擲空指標異常。

    public static <T> T requireNonNull(T obj) {
        if (obj == null)
            throw new NullPointerException();
        return obj;
    }

總結

    其實關於abstratSet抽象類、還有這些集合的介面啊,沒有什麼可以敘述的,具體為什麼這麼設計,說白了就是面向對向設計,OOD,用面向物件的思維來看待JDK中的原始碼,設計無非就是使用 抽象、 封裝、 繼承、 多型這四個特性去做事情,我們學習的23種java設計模式也無非就是抽象封裝繼承多型這四個特性的實現方式。我們把整個集合的框架用介面和抽象類分出層次,一方面是便於開發和理解。另一方面也便於我們擴充套件自己想要實現的東西,也避免了我們去實現一些不必要的東西。