<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    我思故我強(qiáng)

    Set中equals()和hashCode()

    equals()是判讀兩個Set是否相等[前提是equals()在類中被覆蓋]。==決定引用值是否指向同一對象。

    1、當(dāng)向集合set中增加對象時,首先計算要增加對象的hashCode碼,根據(jù)該值來得到一個位置來存放當(dāng)前的對象,當(dāng)在該位置沒有一個對象存在的話,那么集合set認(rèn)為該對象在集合中不存在,直接增加進(jìn)去。如果在該位置有一個對象的話,接著將準(zhǔn)備增加到集合中的對象與該位置上的對象進(jìn)行equals方法比較,如果該equals方法返回false,那么集合認(rèn)為集合中不存在該對象,再進(jìn)行一次散列,將該對象放到散列后計算出的新地址里,如果equals方法返回true,那么集合認(rèn)為集合中已經(jīng)存在該對象了,不會再將該對象增加到集合中了。

    2、當(dāng)重寫equals方法時,必須要重寫hashCode方法。在java的集合中,判斷兩個對象是否相等的規(guī)則是:

    1),判斷兩個對象的hashCode是否相等

          如果不相等,認(rèn)為兩個對象也不相等,完畢 ; 如果相等,轉(zhuǎn)入2

    2),判斷兩個對象用equals運(yùn)算是否相等

          如果不相等,認(rèn)為兩個對象也不相等

          如果相等,認(rèn)為兩個對象相等(equals()是判斷兩個對象是否相等的關(guān)鍵)

        可見hashcode()相等時,equals()方法也可能不等。

    public static void main(String args[]){

    String s1=new String("zhaoxudong"); //此語句創(chuàng)建了兩個對象,一個是字符串對象“zhaoxudong”(存放于棧中的字面量),另一個是new后在堆中產(chǎn)生的對象。詳細(xì)見下面的四.4

    String s2=new String("zhaoxudong");

    //上述兩條語句一共是產(chǎn)生了三個對象,因為棧中只有產(chǎn)生了一個對象。

    System.out.println(s1==s2);//false

    System.out.println(s1.equals(s2));//true

    System.out.println(s1.hashCode());//s1.hashcode()等于s2.hashcode() ,指向同一內(nèi)存的引用

    System.out.println(s2.hashCode()); //equals和hashCode方法只用于兩個對象的比較和容器中,與對象的創(chuàng)建沒有關(guān)系

    Set hashset=new HashSet();

    hashset.add(s1);

    hashset.add(s2); /*在添加s1,s2時, hashset認(rèn)為s1和s2是相等的,所以讓s2覆蓋了s1;*/

    Iterator it=hashset.iterator();

                while(it.hasNext()){

                 System.out.println(it.next());

                } //最后在while循環(huán)的時候只打印出了一個”zhaoxudong”。

    這是因為String類已經(jīng)重寫了equals()方法和hashcode()方法。

    但是看下面的程序:

    public class HashSetTest {

       public static void main(String[] args)   {

                     HashSet hs=new HashSet();

                     hs.add(new Student(1,"zhangsan"));

                     hs.add(new Student(2,"lisi"));

                     hs.add(new Student(3,"wangwu"));

                     hs.add(new Student(1,"zhangsan"));

                     Iterator it=hs.iterator();

                     while(it.hasNext()){

                            System.out.println(it.next());

                     } } }

    class Student {

         int num;

         String name;

         Student(int num,String name) {

                    this.num=num;

                     this.name=name; }

         public String toString() { return num+":"+name; }

               }     

    輸出結(jié)果為:

                       1:zhangsan

                       1:zhangsan

                       3:wangwu

                       2:lisi

    問題出現(xiàn)了,為什么hashset添加了相等的元素呢,這是不是和hashset的原則違背了呢?回答是:沒有因為在根據(jù)hashcode()對兩次建立的new Student(1,"zhangsan")對象進(jìn)行比較時,生成的是不同的哈希碼值,所以hashset把他當(dāng)作不同的對象對待了,當(dāng)然此時的equals()方法返回的值也不等。那么為什么會生成不同的哈希碼值呢?原因就在于我們自己寫的Student類并沒有重新自己的hashcode()和equals()方法,所以在比較時,是繼承的object類中的hashcode()方法,它是一個本地方法,比較的是對象的地址(引用地址),使用new方法創(chuàng)建對象,兩次生成的當(dāng)然是不同的對象了,造成的結(jié)果就是兩個對象的hashcode()返回的值不一樣。那么怎么解決這個問題呢??

    答案是:在Student類中重新hashcode()和equals()方法。

    例如:

    class Student{

    int num;

    String name;

    Student(int num,String name){

                this.num=num;

                this.name=name; }

    public int hashCode(){ //重寫hashCode的方法

                return num*name.hashCode(); }

    public boolean equals(Object o) {

                Student s=(Student)o;

                return num==s.num && name.equals(s.name); //&&的優(yōu)先級比==低,所以前面不必加括號

    }

    public String toString(){return num+":"+name; }

    }

    根據(jù)重寫的方法,即便兩次調(diào)用了new Student(1,"zhangsan"),我們在獲得對象的哈希碼時,根據(jù)重寫的方法hashcode(),獲得的哈希碼肯定是一樣的。所以運(yùn)行修改后的程序時,我們會看到重復(fù)元素的問題已經(jīng)消除。

    在hibernate的pojo類中,經(jīng)常使用set集合來保存相關(guān)對象,而set集合是不允許重復(fù)的。所以需要重寫equals和hashCode()方法。

    比如可以這樣寫:

    public int hashCode(){

       return 1;}//等價于hashcode無效

    這樣做的效果就是在比較哈希碼的時候不能進(jìn)行判斷,因為每個對象返回的哈希碼都是1,每次都必須要經(jīng)過比較equals()方法后才能進(jìn)行判斷是否重復(fù),這當(dāng)然會引起效率的大大降低。

     

    本文來自CSDN博客,轉(zhuǎn)載請標(biāo)明出處:http://blog.csdn.net/elia1208/archive/2009/10/12/4657644.aspx

    posted on 2009-10-14 17:41 李云澤 閱讀(2763) 評論(0)  編輯  收藏 所屬分類: 面試筆試相關(guān)的

    主站蜘蛛池模板: 亚洲欧洲国产成人精品| 无码日韩人妻AV一区免费l | 亚洲精品无码永久在线观看男男| 免费观看的av毛片的网站| 未满十八私人高清免费影院| 91嫩草私人成人亚洲影院| 国产免费久久精品久久久| 国产真人无码作爱视频免费| 中文字幕精品三区无码亚洲| 中文字幕亚洲专区| 手机看黄av免费网址| a级毛片免费高清视频| 亚洲欧洲精品在线| 国产乱辈通伦影片在线播放亚洲| 99re视频精品全部免费| 精品特级一级毛片免费观看| 久久亚洲日韩看片无码| 久久久久亚洲AV无码专区桃色| 日本在线高清免费爱做网站| 中文字幕在线免费播放| 亚洲精品女同中文字幕| 国产亚洲视频在线| 亚洲人成电影在线天堂 | 亚洲中文字幕人成乱码| 久久亚洲AV无码西西人体| 成年女人毛片免费播放视频m| 日韩电影免费在线观看网站| 日韩精品亚洲专区在线影视| 亚洲一级毛片中文字幕| 久久夜色精品国产亚洲AV动态图 | 最新久久免费视频| 亚洲国产成人久久精品动漫 | 最近免费中文字幕大全免费版视频| 黄床大片30分钟免费看| 激情五月亚洲色图| 77777_亚洲午夜久久多人| 久久亚洲AV无码西西人体| 国产又大又长又粗又硬的免费视频| 114级毛片免费观看| 久久免费观看国产精品| 久久国产一片免费观看|