hashCode浅析

  在HashMap中有这么一段
int hash=hash(key.hashCode());
通过对关键字的调用hashCode得到它的编码,其实在java中Class的实例都有hashCode这个方法,hashCode有什么作用呢?怎么实现这个方法呢?

   一,我们先来看看在eclipse中这个hashCode

   1) 创建一个字符串,就可以调用到字符串的hashCode方法,在eclipse下跟踪hashCode这个方法,我们会跟踪到最后的位置是Object类下的
public native int hashCode();
这个位置,到了这里我们就没有下面的跟踪了,那么hashCode到底是怎么实现的呢?到底是吧什么转为hash编码?

    二,在JDK中我们找到hashCode这个方法,在显示中输入Object 通过Ctrl+F 再输入hashCode找到hashCode这个方法。上面是这么写道:

     (1)在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。

     (2)如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。

     (3)如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不 要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。
    
     看了上面的3点,其实最给力的是下面这点:
     实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)

     对于JDK中,还是没有讲到,怎么写hashCode这个方法的,它到底是怎么得到实例的hash值的,以前在做仿压缩软件的时候,用到了哈弗曼树,这个方式得到某一个元素的编码,001,0001,111,100等这些来表示;我们通过哈弗曼树得到的是这种形式下的编码,那么java中hashCode是怎么得到的呢?
   
    三,一个类,这个类可能有很多属性,那么我们怎么得到这个类的实例的hashCode呢?
    下面这个类中方法hashCode把一个类的实例化对象保存成一个hash值(一个32位的带符号整数)Java中实现得到对象的hashCode可能是这样的吧
public class Person{
      int ID;
      String name;
      public int hashCode(){
           int hash = 1;
            hash = hash*17+ID;
            hash = hash*31+name.hashCode();
            return hash;
     }
}

通过这个hashCode()我们计算得到的hashCode值和java中通过调用Person这个的实例对象得到的hashCode值是相同的,大家可以自己去测试一下。

   四,字符串的实例对象可能的实现方法
下面这个得到的是这个字符串的hashCode值,java可能是通过这个方法来得到hashCode 的值。
 public static int calculate_hash(String input)
 {
       int h = 0;
       int len = input.length();
       for (int i = 0; i < len; i++) {
              h = 31 * h + input.charAt(i);
         }
       return h;
    }
}


  通过上面这2个检测的方法,我们可以猜测的到,java中hashCode的实现方法,java中通过比较2个实例的hashCode值,从而确定2个实例是不是一个类的实例化对象。

   参考:[url] http://en.wikipedia.org/wiki/Java_hashCode()[/url]

猜你喜欢

转载自gogoalong.iteye.com/blog/1450249