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