Hash函数
今天看了网易公开课上《算法导论》关于Hash Tables的视频。
Hash函数最简单设计是通过对质数取余的方式进行,但是这涉及到取余运算,并不是一个高效算法。然后视频讲师又提供了另外一个hash函数(《算法导论》中并没有,这里就不给出了),采用乘法和位运算来提高效率。
在Java编程中,如果使用Java API下的Hash数据结构HashTable和HashMap来存储key-value,则会根据key值计算HashCode,所以需要实现该函数。
Java中是如何覆写Hashcode函数的呢?《Think in Java(Fourth Edition)》中“Containers in Depth”中有一小节是“Overriding hashCode()”,这里作者指出该方法来源于《Effective JAVA Programming Language Guide》,该方法非常decent(优雅的,原文形容该方法的词汇)。
Java中覆写Hashcode函数
下面我总结出《Think in Java(Fourth Edition)》中 “Overriding hashCode()”这一小节的步骤:
第1步:定义int result=17,或其他非零值;
第2步:类中重要的成员变量需要参与到hashcode的计算,这里重要是指该成员变量在equals()函数中用来判别类的两个对象是否相等。
第3步:对每一个成员变量,都按下面方式更新这个result。
result=37*result+c;
第4步:返回result即可。
实例
下面是一个实例。
/**
* 三维向量,计算hashCode
* created by 曹艳丰 2016/07/24
* */
public class Vector {
private double x, y, z;
/**
* Constructs a three-component vector with a specified X, Y and Z.
*
* @param x
* the vector's X component
* @param y
* the vector's Y component
* @param z
* the vector's Z component
*/
public Vector(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
@Override
public boolean equals(Object o) {
if (o == null || this.getClass() != o.getClass()) {
return false;
}
Vector that = (Vector) o;
return this.x == that.x && this.y == that.y && this.z == that.z;
}
@Override
public int hashCode() {
int result=17;
long temp;
temp = Double.doubleToLongBits(x);
result = 37*result+(int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(y);
result = 37 * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(z);
result = 37 * result + (int) (temp ^ (temp >>> 32));
return result;
}
}