thinking

          one platform thousands thinking

          關(guān)于hashcode()

          1.hashcode是用來查找的,如果你學(xué)過數(shù)據(jù)結(jié)構(gòu)就應(yīng)該知道,在查找和排序這一章有
          例如內(nèi)存中有這樣的位置
          0     1     2     3     4     5     6     7    
          而我有個(gè)類,這個(gè)類有個(gè)字段叫ID,我要把這個(gè)類存放在以上8個(gè)位置之一,如果不用hashcode而任意存放,那么當(dāng)查找時(shí)就需要到這八個(gè)位置里挨個(gè)去找,或者用二分法一類的算法。
          但如果用hashcode那就會(huì)使效率提高很多。
          我們這個(gè)類中有個(gè)字段叫ID,那么我們就定義我們的hashcode為ID%8,然后把我們的類存放在取得得余數(shù)那個(gè)位置。比如我們的ID為9,9除8的 余數(shù)為1,那么我們就把該類存在1這個(gè)位置,如果ID是13,求得的余數(shù)是5,那么我們就把該類放在5這個(gè)位置。這樣,以后在查找該類時(shí)就可以通過ID除 8求余數(shù)直接找到存放的位置了。

          2.但是如果兩個(gè)類有相同的hashcode怎么辦那(我們假設(shè)上面的類的ID不是唯一的),例如9除以8和17除以8的余數(shù)都是1,那么這是不是合法的,回答是:可以這樣。那么如何判斷呢?在這個(gè)時(shí)候就需要定義   equals了。
          也就是說,我們先通過   hashcode來判斷兩個(gè)類是否存放某個(gè)桶里,但這個(gè)桶里可能有很多類,那么我們就需要再通過   equals   來在這個(gè)桶里找到我們要的類。
          那么。重寫了equals(),為什么還要重寫hashCode()呢?
          想想,你要在一個(gè)桶里找東西,你必須先要找到這個(gè)桶啊,你不通過重寫hashcode()來找到桶,光重寫equals()有什么用啊

          hashCode()是用來產(chǎn)生哈希瑪?shù)模,斒怯脕碓谏⒘写鎯?chǔ)結(jié)構(gòu)中確定對(duì)象的存儲(chǔ)地址的,(這一段在 Java編程思想 中講的很清楚的)象util包中的 帶 hash 的集合類都是用這種存儲(chǔ)結(jié)構(gòu) :HashMap,HashSet, 他們?cè)趯?duì)象存儲(chǔ)時(shí)(嚴(yán)格說是對(duì)象引用),需要確定他們的地址吧, 而HashCode()就是這個(gè)用途的,一般都需要重新定義它的,因?yàn)槟J(rèn)情況下,由 Object 類定義的 hashCode 方法會(huì)針對(duì)不同的對(duì)象返回不同的整數(shù),這一般是通過將該對(duì)象的內(nèi)部地址轉(zhuǎn)換成一個(gè)整數(shù)來實(shí)現(xiàn)的,現(xiàn)在舉個(gè)例子來說, 就拿HashSet來說 ,在將對(duì)象存入其中時(shí),通過被存入對(duì)象的 hashCode() 來確定對(duì)象在 HashSet 中的存儲(chǔ)地址,通過equals()來確定存入的對(duì)象是否重復(fù),hashCode() ,equals()都需要自己重新定義,因?yàn)閔ashCode()默認(rèn)前面已經(jīng)說啦,而equals() 默認(rèn)是比較的對(duì)象引用,你現(xiàn)在想一下,如果你不定義equals()的話,那么同一個(gè)類產(chǎn)生的兩個(gè)內(nèi)容完全相同的對(duì)象都可以存入Set,因?yàn)樗麄兪峭ㄟ^ equals()來確定的,這樣就使得HashSet 失去了他的意義,看一下下面這個(gè):
          import java.util.*;
          /**
          *類說明
          * @author shellfeng E-mail:lsf830804@yahoo.com.cn
          * @version 1.0
          *
          */
          public class Test {
          public static void main(String[] args) {
          HashSet set = new HashSet();
          for (int i = 0; i <= 3; i++){
          set.add(new Demo1(i,i));
          }
          System.out.println(set);
          set.add(new Demo1(1,1));
          System.out.println(set);
          System.out.println(set.contains(new Demo1(0,0)));
          System.out.println(set.add(new Demo1(1,1)));
          System.out.println(set.add(new Demo1(4,4)));
          System.out.println(set);
          }

          private static class Demo1 {
          private int value;

          private int id;

          public Demo1(int value,int id) {
          this.value = value;
          this.id=id;
          }

          public String toString() {
          return " value = " + value;
          }

          public boolean equals(Object o) {
          Demo1 a = (Demo1) o;
          return (a.value == value) ? true : false;
          }

          public int hashCode() {
          return id;
          }
          }
          }
          你分別注釋掉hashCode()和 equals()來比較一下他們作用就可以拉,關(guān)鍵要自己動(dòng)手看看比較的結(jié)果你就可以記得很清楚啦
          結(jié)果:
          [ value = 2,  value = 1,  value = 3,  value = 0]
          [ value = 2,  value = 1,  value = 3,  value = 0]
          true
          false
          true
          [ value = 2,  value = 4,  value = 1,  value = 3,  value = 0]

          注釋掉hashCode()
          [ value = 1,  value = 0,  value = 2,  value = 3]
          [ value = 1,  value = 0,  value = 1,  value = 2,  value = 3]
          false
          true
          true
          [ value = 1,  value = 0,  value = 1,  value = 2,  value = 3,  value = 4,  value = 1]

          注釋掉equals()
          [ value = 2,  value = 1,  value = 3,  value = 0]
          [ value = 2,  value = 1,  value = 1,  value = 3,  value = 0]
          false
          true
          true
          [ value = 2,  value = 4,  value = 1,  value = 1,  value = 1,  value = 3,  value = 0]

          hashCode()方法使用來提高M(jìn)ap里面的搜索效率的,Map會(huì)根據(jù)不同的hashCode()來放在不同的桶里面,Map在搜索一個(gè)對(duì)象的時(shí)候先 通過hashCode()找到相應(yīng)的桶,然后再根據(jù)equals()方法找到相應(yīng)的對(duì)象.要正確的實(shí)現(xiàn)Map里面查找元素必須滿足一下兩個(gè)條件:
          (1)當(dāng)obj1.equals(obj2)為true時(shí)obj1.hashCode() == obj2.hashCode()必須為true
          (2)當(dāng)obj1.hashCode() == obj2.hashCode()為false時(shí)obj.equals(obj2)必須為false


          posted on 2009-02-16 10:54 lau 閱讀(562) 評(píng)論(0)  編輯  收藏


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 伊金霍洛旗| 长顺县| 东乡县| 射阳县| 双鸭山市| 邯郸县| 姚安县| 碌曲县| 德格县| 钟山县| 柯坪县| 新巴尔虎右旗| 新绛县| 朝阳区| 衡南县| 康马县| 衡水市| 宁武县| 西丰县| 彩票| 万州区| 通榆县| 西吉县| 沅江市| 海盐县| 宕昌县| 右玉县| 资兴市| 旬阳县| 朝阳市| 济阳县| 大邑县| 额济纳旗| 民权县| 阿合奇县| 麻阳| 晋州市| 图木舒克市| 忻州市| 乌鲁木齐市| 安化县|