散列码(hash code)是由对象导出的一个整型值,散列码是没有规律的,如果x和y 的是两个不同的对象,x.hashCode()和y.hashCode()基本上不会相同。
由于hashCode方法定义在Object类中,因此每个对象都有一个默认的散列码,其值是对象的存储地址。
String str = new String("12");
String str1 = str;
System.out.println(str == str1);
System.out.println(str.hashCode());
System.out.println(str1.hashCode());
结果:
true
1569
1569
对于哈希的几种情况,我们还是通过代码来看一下吧,
public class Hash {
static int [] a = new int[5];
static int [] n = a;
static int [] v = new int[5];
static String sd = "100";
double [] b = new double [6];
double [] ddd = new double [7];
public static void main(String[] args) {
System.out.println(a.equals(v));//false
System.out.println(a.equals(n));//true
Integer ss = 10230;
System.out.println(ss.hashCode());//10230
System.out.println(Integer.MAX_VALUE);//2147483647
Integer a=34556,b=34556;
System.out.println("Integer : a = b ? :"+a.equals(b));//Interger : a = b ? :true
System.out.println(a==b);//false
Integer a1=36,b1=36;
System.out.println(a1==b1);//true 按说应该是说false 其实是true 这涉及到对象池的大
//小 -128~128
System.out.println("Interger : a1 = b1 ? :"+a1.equals(b1));//true
String sss = "100";
String ssss = "100";
System.out.println(sss.hashCode());//48625
System.out.println(sss==ssss);//true
System.out.println(ssss.hashCode());//48625
System.out.println("sd:"+sd.hashCode());//sd:48625
Worker w1 = new Worker("小明",22);
System.out.println(w1.hashCode());//118352462
Worker w2 = new Worker("小刚",30);
System.out.println(w2.hashCode());//1550089733
System.out.println();
long l1 = 1282222222222222222L;
long l2 = 1282222222222222222L;
System.out.println(l1==l2);//true
String str = new String("12");
String str1 = str;
System.out.println(str == str1);//ture
System.out.println(str.hashCode());//1569
System.out.println(str1.hashCode());//1569
//System.out.println(aa.hashCode());
//865113938 int [] aa = {1,2};
//865113938 int [] aa = {1};
//865113938 int [] aa = {2};
//865113938 int [] aa = {};
//865113938 static int [] aa= {};
System.out.println(a.hashCode());//34556
System.out.println(b.hashCode());//34556
//System.out.println(ddd.hashCode());
}
}
首先对于数组类型,数组类型是引用类型,如果两个数组类型的变量指向同一个引用,他们的哈希值是一样的,另外发现一点,数组变量返回的哈希值与数组中有无值和值的大小,数量没有关系。数组类型的引用在堆中开辟了一块空间,然后数组变量返回的哈希值是这块空间的地址,所以和里面的值没有关系,但是对于equals方法来说,就和值有关了。
int [] aa = {1,2};
int [] aa1 = aa;
System.out.println( "aa aa1 ? "+aa.equals(aa1));
int [] aa2 = {1,2};
System.out.println("aa aa2 ? "+aa.equals(aa2));
int [] aa3 = {1,2,3};
System.out.println( "aa aa3 ? "+aa.equals(aa3));
结果:
aa aa1 ? true
aa aa2 ? false
aa aa3 ? false
对于对象类型,对象类型也是引用类型,对象调用哈希方法返回该对象在堆中的存储地址。和数组类型的一样,和其中的值无关,哈希方法只是返回内存中的存储地址。
String类型,算是个特殊的情况吧,这和Java中字符串类型的存储原理相关了。在Java中,只要的字符串的值是相同的,不同的变量名都指向这块存储空间。对于String类型的变量,如果字符串a和b指向变量池中的同一个值,就认为a和b有着同样的散列码。所以,对于String类型的hashCode方法和equals方法,只需要看变量的值就可以了。
Integet类型,你可能会问为什么上面代码中的两次==方法比较的结果方法不同,或者说为什么第二次的返回结果是true?
这是因为Interger类型的变量值在正负128的范围内默认的是数值类型,超出这个范围,才是引用类型。