首先,hashCode就是一種查找的索引值。就好比一個(gè)數(shù)組,你用數(shù)組下標(biāo)來(lái)查找你的數(shù)組元素,同樣,hashCode來(lái)查找hashTable中的存儲(chǔ)元素。當(dāng)然,作為散列方式的查找和存儲(chǔ),要比數(shù)組這種線性數(shù)據(jù)結(jié)構(gòu)復(fù)雜的多。這涉及到hash函數(shù)的構(gòu)造, hash Collision等問(wèn)題,數(shù)據(jù)結(jié)構(gòu)中。
而每個(gè)對(duì)象在內(nèi)存當(dāng)中的存儲(chǔ)組織方式就是利用這種散列方式存儲(chǔ),當(dāng)然也就有它的 hashCode了,如果想獲取這個(gè)對(duì)象在Hash表中的位置,就可以調(diào)用 Object.hashCode() 結(jié)果返回int型。還有一點(diǎn)需要注意的是:hashcode 相等,則對(duì)象一定一樣;hashcode 不相等,對(duì)象 也可能相等(不是相同), 如果對(duì)于不等的對(duì)象構(gòu)造不同的hashCode那么將會(huì)提高 hash表的性能。(具體原因可以查看數(shù)據(jù)結(jié)構(gòu)中hash表的構(gòu)造方式)
下面的兩個(gè)程序是hashcode的理解:
student.java
下面的兩個(gè)程序是hashcode的理解:
student.java
package core_java;
public class Student {
private String name;
private int age;
public Student(String name,int age){
this.name = name;
this.age = age;
}
public int hashCode(){
return 7*name.hashCode()+13*age;
}
}
在同一個(gè)包下 Testhashcode.javapublic class Student {
private String name;
private int age;
public Student(String name,int age){
this.name = name;
this.age = age;
}
public int hashCode(){
return 7*name.hashCode()+13*age;
}
}
package core_java;
public class Testhashcode {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Student stu1 = new Student("aa",17);
Student stu2 = new Student("aa",17);
System.out.println(stu1);
System.out.println(stu2);
System.out.println(stu1 == stu2);
}
}
得出的結(jié)果:public class Testhashcode {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Student stu1 = new Student("aa",17);
Student stu2 = new Student("aa",17);
System.out.println(stu1);
System.out.println(stu2);
System.out.println(stu1 == stu2);
}
}
core_java.Student@55bd
core_java.Student@55bd
false
說(shuō)明:1.system.out.println(Object)輸出的是Object.toString(),Student類重寫了hashcode方法,如果不重寫則結(jié)果不一樣
2.== 比較的不僅僅是對(duì)象在虛擬機(jī)中的內(nèi)存地址
深入了解hashcode與內(nèi)存分配:
HashCodeMeaning.java
補(bǔ)充:
說(shuō)明:1.system.out.println(Object)輸出的是Object.toString(),Student類重寫了hashcode方法,如果不重寫則結(jié)果不一樣
2.== 比較的不僅僅是對(duì)象在虛擬機(jī)中的內(nèi)存地址
深入了解hashcode與內(nèi)存分配:
HashCodeMeaning.java
package com.leo.test.action;
import java.util.ArrayList;
/**
* @author MK
*
* 此方法的作用是證明 java.lang.Object的hashcode 不是代表 對(duì)象所在內(nèi)存地址。
* 我產(chǎn)生了10000個(gè)對(duì)象,這10000個(gè)對(duì)象在內(nèi)存中是不同的地址,但是實(shí)際上這10000個(gè)對(duì)象
* 的hashcode的是完全可能相同的
*/
public class HashCodeMeaning {
public static void main(String[] args) {
ArrayList list = new ArrayList();
int numberExist=0;
//證明hashcode的值不是內(nèi)存地址
for (int i = 0; i < 10000; i++) {
Object obj=new Object();
if (list.contains(obj.toString())) {
System.out.println(obj.toString() +" exists in the list. "+ i);
numberExist++;
}
else {
list.add(obj.toString());
}
}
System.out.println("repetition number:"+numberExist);
System.out.println("list size:"+list.size());
//證明內(nèi)存地址是不同的。
numberExist=0;
list.clear();
for (int i = 0; i < 10000; i++) {
Object obj=new Object();
if (list.contains(obj)) {
System.out.println(obj +" exists in the list. "+ i);
numberExist++;
}
else {
list.add(obj);
}
}
System.out.println("repetition number:"+numberExist);
System.out.println("list size:"+list.size());
}
}
運(yùn)行輸出結(jié)果:import java.util.ArrayList;
/**
* @author MK
*
* 此方法的作用是證明 java.lang.Object的hashcode 不是代表 對(duì)象所在內(nèi)存地址。
* 我產(chǎn)生了10000個(gè)對(duì)象,這10000個(gè)對(duì)象在內(nèi)存中是不同的地址,但是實(shí)際上這10000個(gè)對(duì)象
* 的hashcode的是完全可能相同的
*/
public class HashCodeMeaning {
public static void main(String[] args) {
ArrayList list = new ArrayList();
int numberExist=0;
//證明hashcode的值不是內(nèi)存地址
for (int i = 0; i < 10000; i++) {
Object obj=new Object();
if (list.contains(obj.toString())) {
System.out.println(obj.toString() +" exists in the list. "+ i);
numberExist++;
}
else {
list.add(obj.toString());
}
}
System.out.println("repetition number:"+numberExist);
System.out.println("list size:"+list.size());
//證明內(nèi)存地址是不同的。
numberExist=0;
list.clear();
for (int i = 0; i < 10000; i++) {
Object obj=new Object();
if (list.contains(obj)) {
System.out.println(obj +" exists in the list. "+ i);
numberExist++;
}
else {
list.add(obj);
}
}
System.out.println("repetition number:"+numberExist);
System.out.println("list size:"+list.size());
}
}
java.lang.Object@922804 exists in the list. 1778
java.lang.Object@e29820 exists in the list. 2077
repetition number:2
list size:9998
repetition number:0
list size:10000
說(shuō)明:
存入hashcode到list中時(shí)不同對(duì)象的hashcode有可能相等,而不同對(duì)象的內(nèi)存地址是不相等的
現(xiàn)在腦子里還有點(diǎn)混亂 需要深刻理解下。
哪位可以給我點(diǎn)詳細(xì)的資料啊?
說(shuō)明:
存入hashcode到list中時(shí)不同對(duì)象的hashcode有可能相等,而不同對(duì)象的內(nèi)存地址是不相等的
現(xiàn)在腦子里還有點(diǎn)混亂 需要深刻理解下。
哪位可以給我點(diǎn)詳細(xì)的資料啊?
補(bǔ)充:
如果一個(gè)類沒(méi)有自己定義equals方法,它默認(rèn)的equals方法(從Object 類繼承的)就是使用==操作符,也是在比較兩個(gè)變量指向的對(duì)象是否是同一對(duì)象,這時(shí)候使用equals和使用==會(huì)得到同樣的結(jié)果,如果比較的是兩個(gè)獨(dú)立的對(duì)象則總返回false。如果你編寫的類希望能夠比較該類創(chuàng)建的兩個(gè)實(shí)例對(duì)象的內(nèi)容是否相同,那么你必須覆蓋equals方法,由你自己寫代碼來(lái)決定在什么情況即可認(rèn)為兩個(gè)對(duì)象的內(nèi)容是相同的。