首先,hashCode就是一種查找的索引值。就好比一個數組,你用數組下標來查找你的數組元素,同樣,hashCode來查找hashTable中的存儲元素。當然,作為散列方式的查找和存儲,要比數組這種線性數據結構復雜的多。這涉及到hash函數的構造, hash Collision等問題,數據結構中。
而每個對象在內存當中的存儲組織方式就是利用這種散列方式存儲,當然也就有它的 hashCode了,如果想獲取這個對象在Hash表中的位置,就可以調用 Object.hashCode() 結果返回int型。還有一點需要注意的是:hashcode 相等,則對象一定一樣;hashcode 不相等,對象 也可能相等(不是相同), 如果對于不等的對象構造不同的hashCode那么將會提高 hash表的性能。(具體原因可以查看數據結構中hash表的構造方式)
下面的兩個程序是hashcode的理解:
student.java
下面的兩個程序是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;
}
}
在同一個包下 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);
}
}
得出的結果: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
說明:1.system.out.println(Object)輸出的是Object.toString(),Student類重寫了hashcode方法,如果不重寫則結果不一樣
2.== 比較的不僅僅是對象在虛擬機中的內存地址
深入了解hashcode與內存分配:
HashCodeMeaning.java
補充:
說明:1.system.out.println(Object)輸出的是Object.toString(),Student類重寫了hashcode方法,如果不重寫則結果不一樣
2.== 比較的不僅僅是對象在虛擬機中的內存地址
深入了解hashcode與內存分配:
HashCodeMeaning.java
package com.leo.test.action;
import java.util.ArrayList;
/**
* @author MK
*
* 此方法的作用是證明 java.lang.Object的hashcode 不是代表 對象所在內存地址。
* 我產生了10000個對象,這10000個對象在內存中是不同的地址,但是實際上這10000個對象
* 的hashcode的是完全可能相同的
*/
public class HashCodeMeaning {
public static void main(String[] args) {
ArrayList list = new ArrayList();
int numberExist=0;
//證明hashcode的值不是內存地址
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());
//證明內存地址是不同的。
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());
}
}
運行輸出結果:import java.util.ArrayList;
/**
* @author MK
*
* 此方法的作用是證明 java.lang.Object的hashcode 不是代表 對象所在內存地址。
* 我產生了10000個對象,這10000個對象在內存中是不同的地址,但是實際上這10000個對象
* 的hashcode的是完全可能相同的
*/
public class HashCodeMeaning {
public static void main(String[] args) {
ArrayList list = new ArrayList();
int numberExist=0;
//證明hashcode的值不是內存地址
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());
//證明內存地址是不同的。
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
說明:
存入hashcode到list中時不同對象的hashcode有可能相等,而不同對象的內存地址是不相等的
現在腦子里還有點混亂 需要深刻理解下。
哪位可以給我點詳細的資料啊?
說明:
存入hashcode到list中時不同對象的hashcode有可能相等,而不同對象的內存地址是不相等的
現在腦子里還有點混亂 需要深刻理解下。
哪位可以給我點詳細的資料啊?
補充:
如果一個類沒有自己定義equals方法,它默認的equals方法(從Object 類繼承的)就是使用==操作符,也是在比較兩個變量指向的對象是否是同一對象,這時候使用equals和使用==會得到同樣的結果,如果比較的是兩個獨立的對象則總返回false。如果你編寫的類希望能夠比較該類創建的兩個實例對象的內容是否相同,那么你必須覆蓋equals方法,由你自己寫代碼來決定在什么情況即可認為兩個對象的內容是相同的。