java.lang.Object.hashCode()方法

Object类的一个重要方法之一:hashCode();首先看一下Object中对此方法的定义:

 /**
     * Returns a hash code value for the object. This method is
     * supported for the benefit of hash tables such as those provided by
     * {@link java.util.HashMap}.
     * 

* The general contract of {@code hashCode} is: *

    *
  • Whenever it is invoked on the same object more than once during * an execution of a Java application, the {@code hashCode} method * must consistently return the same integer, provided no information * used in {@code equals} comparisons on the object is modified. * This integer need not remain consistent from one execution of an * application to another execution of the same application. *
  • If two objects are equal according to the {@code equals(Object)} * method, then calling the {@code hashCode} method on each of * the two objects must produce the same integer result. *
  • It is not required that if two objects are unequal * according to the {@link java.lang.Object#equals(java.lang.Object)} * method, then calling the {@code hashCode} method on each of the * two objects must produce distinct integer results. However, the * programmer should be aware that producing distinct integer results * for unequal objects may improve the performance of hash tables. *
*

* As much as is reasonably practical, the hashCode method defined by * class {@code Object} does return distinct integers for distinct * objects. (This is typically implemented by converting the internal * address of the object into an integer, but this implementation * technique is not required by the * Java™ programming language.) * * @return a hash code value for this object. * @see java.lang.Object#equals(java.lang.Object) * @see java.lang.System#identityHashCode */ public native int hashCode();

这里的注释说的很清楚: hashCode()方法的作用是返回一个对象的hash值,下面是一些常规的约定

1.在运行的同一个Java应用程序中,如果一个对象多次执行hashCode()方法,必须都返回同一个hash值。

2.如果通过equals()方法判断的两个相等的对象,则调用hashCode()时也会返回同一个hash值。

3.对于equals()方法判断不等的两个对象却没有必要返回不同的hash值,也就是说,如果两个对象不等,却返回同一个hash值,这个是正常的现象。所以说如果hashCode()的值相等,则两个对象equals()不一定相等;但是当两个对象equals()相等,则hashCode()一定相等。但是,程序员应该要注意一个问题,那就是对不相等的对象返回不同的hash值能有效提升hash表的性能。

因为Java中所有的类都是Object类的子类,所以所有类都有hashCode()方法,比如Integer的hashCode()方法就返回Integer值本身,这里以String的实现为例,看一下hashCode()方法是如何实现的,首先看下代码:

 /**
     * Returns a hash code for this string. The hash code for a
     * {@code String} object is computed as
     * 
     * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
     * 
* using {@code int} arithmetic, where {@code s[i]} is the * ith character of the string, {@code n} is the length of * the string, and {@code ^} indicates exponentiation. * (The hash value of the empty string is zero.) * * @return a hash code value for this object. */ 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; }

这里的value定义:
/** The value is used for character storage. */
private final char value[];

表示是用来存储字符数组,也就是说如果传入一个aaa的字符串,这里的value就是['a','a','a']数组。这里以aaa字符串为例说明hashCode()获得hash值得过程。

定义一个String str = "aaa";

在进入hashCode()方法中时,value的值为['a','a','a'],这里hash的值默认初始为0,根据hashCode()实现算法:s[0]31^(n-1) + s[1]31^(n-2) + ... + s[n-1],进入for循环后,

(1). 第一次循环, h = 31 * 0 + a,这里由于a是char类型,而h是int类型,那这里就涉及到了char类型转为int类型,也就是字符对应的ASCII码值,'a'字符转换为ASCII码为97,所以这里的h值为97;

(2). 第二次循环,h = 31 * 97 + 97,为3104;

(3). 第三次循环,h = 3104 * 97 + 97,为96321。

所以字符串"aaa"对应的hash值为96321,这是String类对hashCode()方法的实现。
hashCode()方法经常用在一些数据的存储、比较、分类等场景中用到,比如之前我看到的一个java的面试题目:给定a、b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4G,让你找出a、b文件共同的url?这种问题的解决办法用分而治之就可以实现,获取每个url的hash值,如果两个url相等,那么其hash值一定相等。所以这种思想是可以很好的去解决一些实际的问题的。





你可能感兴趣的:(Java)