判斷Set里的元素是否重復、==、equals、hashCode方法研究-代碼演示



 

        SiteBean site1 = new SiteBean("http://www.yjbys.com/", "");
        SiteBean site2 = new SiteBean("http://www.yjbys.com/", "");
        Set<SiteBean> aaSet = new HashSet<>();
        aaSet.add(site1);
        aaSet.add(site2);
System.out.println(site1
== site2); System.out.println(site1.equals(site2)); System.out.println(site1.hashCode() == site2.hashCode()); SiteBean site3 = new SiteBean("http://www.yjby1s.com/11", ""); SiteBean site4 = new SiteBean("http://www.yjby1s.com/11", ""); aaSet.add(site3); aaSet.add(site4);
SiteBean 重寫了hashCode和equals方法,代碼如下:

 //比較的是域名
    @Override
    public int hashCode() {
        return siteUrl.hashCode();
    }

    //比較的是域名
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }

        if (getClass() != obj.getClass()) {
            return false;
        }
        final SiteBean siteBean = (SiteBean) obj;
        return Objects.equals(siteUrl, siteBean.siteUrl);
    }

輸出如下:

false
true
true
且set中元素的個數是2.

 

set內部實現實際是map,在處理map的key的時候調用了hashcode方法,HashMap中有代碼如下

 static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

 

下面嘗試不重寫hashcode方法,即默認使用Object的hashcode方法(代碼省略):

輸出:

false
true
false
且set中元素的個數是4

    調試證明:把元素往set中添加時,首先會對比hashcode是否相等,如果hashcode不相等就直接往set中加這個元素,如果hashcode相等就對比equals方法,如果equals不相等就往set中加這個元素,所以set的元素重復性是根據hashcode和equals方法來判斷的,

    對於為什么覆蓋equals方法就一定要覆蓋hashcode方法的原因也顯示了出來:由於是先調用hashcode方法的,如果不覆蓋hashcode方法,默認會去取內存的物理地址作為生成hashcode的依據,那么兩個不同的對象的hashcode必然不同的,於是直接結束添加了,根本沒法調用到equals方法,就不用說equals內部實現如何了,不管equals是返回true還是false都沒機會調用到了。

    由於set內部是用map實現的,所以往map中put元素的時候是一樣的原理。

 

下面嘗試不重寫hashcode和equals方法(代碼省略):

輸出:

false
false false
且set中元素的個數是4

證明如果不重寫hashcode方法,無論equals是返回true還是返回false都沒有用,因為在調用equals方法之前會先調用hashcode方法,在調用hashcode方法的時候

就已經被認為這些對象全部是不重復的元素,直接往set中添加這些對象,並完成添加,equals方法就沒有機會調用到。

作者:歐初權

轉載注明:http://www.cnblogs.com/langtianya/p/4421582.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM