Java的Object对象中定义了hashCode()方法,代码如下:
public native int hashCode();
native关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其他语言(如C和C++)实现的文件中。Java语言本身不能对操作系统底层进行访问和操作,但是可以通过JNI接口调用其他语言来实现对底层的访问。一般情况下,根据对象的内存地址计算该对象的哈希值.
hashCode在JAVA中,代表了对象的一种特征。不同的对象哈希码是不同的。
哈希码是一种数据结构算法,在JAVA中,常见的哈Java对象获取到的哈希码具体值是多少?
一、Integer
Integer类型对象的哈希值就是它自己的值。
实例1:
Integer a=23;
Integer b=new Integer(23);
System.out.println(a.hashCode()+" "+b.hashCode());
//判断hashCode是否相同
System.out.println(a.hashCode()==b.hashCode());
//判断值是否相同
System.out.println(a.equals(b));
//判断对象是否相同
System.out.println(a==b);
输出结果:
23 23
true
true
false
实例2:
Integer a=23;
Integer b=23;
System.out.println(a.hashCode()+" "+b.hashCode());
//判断hashCode是否相同
System.out.println(a.hashCode()==b.hashCode());
//判断值是否相同
System.out.println(a.equals(b));
//判断对象是否相同
System.out.println(a==b);
输出结果:
23 23
true
true
true
实例3:
Integer a=128;
Integer b=128;
System.out.println(a.hashCode()+" "+b.hashCode());
//判断hashCode是否相同
System.out.println(a.hashCode()==b.hashCode());
//判断值是否相同
System.out.println(a.equals(b));
//判断对象是否相同
System.out.println(a==b);
输出结果:
128 128
true
true
false
二、String
对于String对象的哈希值,Java中用下面的数学表达式来计算:
;其中n是String的长度,^是幂运算符,空字符串的哈希码值为0。比如String a="10";哈希码为1567=49*31+48
三、Boolean
如果Boolean的对象值为true,则对应哈希码值为1231,如果Boolean的对象值为false,则对应哈希码值为1237。
四、Float
单精度对象f的hashcode的值等于Float.floatToIntBits(f)的值,其中floatToIntBits方法根据IEEE 754 浮点“单一格式”位布局,返回指定浮点值的表示形式,在所有情况下,结果都是一个整数。
实例1:
Float a=0.10f;
Float b=0.1f;
System.out.println(a.floatValue());
System.out.println(Float.floatToIntBits(a.floatValue()));
System.out.println(a.hashCode()+" "+b.hashCode());
//判断hashCode是否相同
System.out.println(a.hashCode()==b.hashCode());
//判断值是否相同
System.out.println(a.equals(b));
//判断对象是否相同
System.out.println(a==b);
执行结果:
0.1
1036831949
1036831949 1036831949
true
true
false
五、Double
在Java中,如何计算Double的哈希值了?计算表达式如下:
(int)(v^(v>>>32)) ,其中>>>无符号右移,忽略符号位,空位都以0补齐,^ 运算符对整数操作数执行按位“异或”运算:
0 ^ 1 = 1
1 ^ 1 = 0
0 ^ 0 = 0
1 ^ 0 = 1
v 为long类型,v = Double.doubleToLongBits(this.doubleValue());
Double.doubleToLongBits方法根据 IEEE 754浮点双精度格式
jdk源码:
public int hashCode() {
long bits = doubleToLongBits(value);
return (int)(bits ^ (bits >>> 32));
}
double对象hashcode计算的方法:
1、先要计算出double对象的 bits=doubleToLongBits(double value)
2、 再无符号右移32位,
3、 再和bits进行异或计算
实例1:
Double a=2121.1000;
Double b=new Double(2121.1);
System.out.println(Double.doubleToLongBits(a));
System.out.println(Double.doubleToLongBits(b));
System.out.println(a.hashCode()+" "+b.hashCode());
//判断hashCode是否相同
System.out.println(a.hashCode()==b.hashCode());
//判断值是否相同
System.out.println(a.equals(b));
//判断对象是否相同
执行结果:
4656882763301073715
4656882763301073715
1939054848 1939054848
true
true
false
注意,不能用==来判断Double对象的值是否相同,==是用来判断对象是否是同一个对象,如果想判断Double对象的值是否相同,用Float.floatToIntBits()方法即可。
六、自定义对象
6.1采用默认的hashCode
定义类对象
import java.io.Serializable;
public class Coordinateimplements Serializable{
private static final long serialVersionUID = 1L;
public double getLat() {
return lat;
}
public void setLat(double lat) {
this.lat = lat;
}
public double getLng() {
return lng;
}
public void setLng(double lng) {
this.lng = lng;
}
private double lat;//纬度
private double lng;//经度
public Coordinate() {
// TODO Auto-generated constructor stub
}
public Coordinate(double lat,double lng) {
super();
this.lat = lat;
this.lng = lng;
}
}
测试代码:
Coordinate a=new Coordinate(12,34);
Coordinate b=new Coordinate(12,34);
//Coordinate b=a;
System.out.println(a.hashCode()+" "+b.hashCode());
//判断hashCode是否相同
System.out.println(a.hashCode()==b.hashCode());
//判断值是否相同
System.out.println(a.equals(b));
//判断对象是否相同
System.out.println(a==b);
输出结果:
2132919775 38139054
false
false
false
在一个应用程序之内,相同的对象的哈希值相同。不同的对象的哈希值不相同。在不同的应用程序之内,即使是同一个对象,哈希值不同,这是因为默认是根据对象的地址来计算哈希值的,地址变了,哈希值也变了。
6.2 重写hashCode()和equals()
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(lat);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(lng);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj ==null)
return false;
if (getClass() != obj.getClass())
return false;
Coordinate other = (Coordinate) obj;
if (Double.doubleToLongBits(lat) != Double.doubleToLongBits(other.lat))
return false;
if (Double.doubleToLongBits(lng) != Double.doubleToLongBits(other.lng))
return false;
return true;
}
运行上面的测试代码:
结果为:
85525441 85525441
true
true
False