现在的位置: 首页 > 综合 > 正文

Thinking in Java之hashCode()方法

2013年12月21日 ⁄ 综合 ⁄ 共 2442字 ⁄ 字号 评论关闭

       欢迎讨论、交流,转载请注明出处,3Q!

       前言

             一直对hashCode()这个方法由困惑,也不知道什么时候该去实现hashCode()方法。趁着研究

          源码的这段时间吧hashCode()方法做一个总结。

       HashCode返回值

              Java中每个对象都是Object的子类,也就用于hashCode()方法,查看源码可以知道,hashCode()

          方法返回的是一个整数,这有什么实际含义吗?

              其实hashCode()方法返回的是对象的哈希码,那么对象的哈希码又是个什么东东?

          简单的来书对象的哈希码代表了对象的特征。对象的特征有阵各种的表现形式,例如对象的物理

          地址,字符串内容,或者数字算出来的int类型的数值。哈希码既然用于表示对象的特征,就可以

          用于判断对象是否相等,所以在实际情况下如果对象通过equals方法是相等的,那么其hashCode

          返回的值也是相等的。例如String类。  

package com.kiritor;

public class HashTest {
  public static void main(String[] args) {
	String a = "AAA";
	String b ="AAA";
	System.out.println(a.hashCode());
	System.out.println(b.hashCode());
}
}

              两句Sysout语句输出的结果都是一样的!Object的hashCode()方法其实就是根据对象的物理地

          址生成的hash值,Object的equals方法判断的也是物理地址。这里由于Object的hashCode方法是

          native的我们就解析下String 类的hashCode的源码吧:

 public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

            可以看见的是String的hashCode就是根据字符串的内容来的,而其equals方法比较的也是字符串的

         内容。

   public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String) anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                            return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

       哈希码的作用   

               现在我们知道了hashCode方法产生的是对象的哈希值(对象特征)。但是对于对象的比较我们有equals

           方法了,还需要hashCode()方法干什么?

               其一:在不自己实现hashCode()方法的情况下描述的是对象的物理地址信息,而我们一般重写equals

           方法进行对象的判等,对于对象的物理地址的描述信息有必要保存。

               其二:java集合中存在一种无序但元素不重复的集合例如HashMap,保证元素不重复这个可以通过

           equals方法来实现,不过当元素过多的时候,后添加的元素必然比较的次数过多。此时hashCode就非常

           有用了,因为其返回的是一个整数,我们可以对这个哈希值做相关处理形成对象插入数组的索引。

               实现内部哈希排序:哈希映射技术。

               关于内部哈希排序可参考这篇文章:

                http://blog.csdn.net/kiritor/article/details/8884371

                在HashMap集合映射中采用了哈希表的原理,哈希算法也成为散列算法,就是将数据依照特定的

          算法直接指定到一个地址上。

               当集合要添加元素的时候,首先得到这个元素的hashCode方法,在通过hash算法定位到放置的物理

          地址,若此刻这个位置没有元素则直接存储在这个位置,若有则调用equals判断相同就不存,不同的话就

          重新进行散列(这里并没有针对哪种集合只是说明这个问题)

         总结

                  hashCode()方法返回的是对象的特征(物理地址、内容等),他和equals方法比起来更像是对象的编码

           equals更像是对象的内容判断。

                  如果两个对象是相等的,那么他们的hashCode方法一定要相等才是合理的;若果两个对象的

           hashCode相等,他们可能是不相等的。上述对象的相等是有equals判断的。

                  因此对于equals方法和hashCode方法来说,他们总应该保持逻辑上的一致关系。在重写equals方法的

           时候也尽量的重写hashCode方法。

              

抱歉!评论已关闭.