Java學習筆記15:java中的hashcode雜湊碼、hash 演算法
推薦一篇好文章:深入理解 hashcode 和 hash 演算法https://blog.csdn.net/qq_38182963/article/details/78940047
為什麼使用 hashcode ?
hashCode 存在的第一重要的原因就是在 HashMap(HashSet 其實就是HashMap) 中使用(其實Object 類的 hashCode 方法註釋已經說明)
HashMap 之所以速度快,因為使用散列表。根據 key 的 hashcode值生成陣列下標(通過記憶體地址直接查詢,沒有任何判斷),時間複雜度完美情況下可以達到 n1(和陣列相同,但是比陣列用著爽多了,但是需要多出很多記憶體,相當於以空間換時間)。
在Java中,雜湊碼代表了物件的一種特徵,例如我們判斷某兩個字串是否==,如果其雜湊碼相等,則這兩個字串是相等的。
其次,雜湊碼是一種資料結構的演算法。
常見的雜湊碼的演算法有:
-
Object類的hashCode.返回物件的記憶體地址經過處理後的結構,由於每個物件的記憶體地址都不一樣,所以雜湊碼也不一樣。
-
String類的hashCode.根據String類包含的字串的內容,根據一種特殊演算法返回雜湊碼,只要字串內容相同,返回的雜湊碼也相同。
-
Integer類,返回的雜湊碼就是Integer物件裡所包含的那個整數的數值,例如:
Integer i1=new Integer(100);
i1.hashCode的值就是100 。由此可見,兩個一樣大小的Integer物件,返回的雜湊碼也一樣。
4.布林型別的雜湊碼: https://blog.csdn.net/github_38838414/article/details/80502964
public static void main(String []args) { Boolean b2=true; Boolean b3=false; System.out.println("ture的hash值:"+b2.hashCode()); System.out.println("false的hash值:"+b3.hashCode()); }
輸出結果:
ture的hash值:1231
false的hash值:1237
為什麼是1231和1237,而不是我們經常用的1和0?
不管使用什麼雜湊演算法,其雜湊函式都要極可能避免衝突。簡單地說,不同的值要落在不同的存貯單元。認真觀察,很容易發現1231和1237都是素數。使用素數的好處在於,對於不同數目的存貯單元m,1231和1237基本上都與其互質,除非m等於或數倍於1231和1237。這種情況下,true和false也能落到不同的單元去。
其實這也就是一般hash演算法取值的預設規則,取素數。
例項:
package create;
public class Demo1_hashCode {
public static void main(String[] args){
Object obj1=new Object();
int hashCode=obj1.hashCode();
System.out.println(hashCode);
String s1="張三";
String s2="張三";
String s3="李四";
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println(s3.hashCode());
Integer i1=new Integer(100);
System.out.println(i1.hashCode());
}
}
輸出結果為:
31168322
774889
774889
842061
100
以下為轉載程式碼:
package new_start1;
public class Test1 {
class Person
{
public String name;
public Person(String n)
{
this.name=n;
}
public Person(){}
}
public static void change(Person a)//改變物件a的name值
{
a.name="haha";
}
public static void main(String[] args) {
Test1 t=new Test1();
Person p=t.new Person("zhangsan"); //例項一個物件p
Person a=t.new Person();//又例項一個物件a
System.out.println("未賦值前,兩者的雜湊碼是不相同的:");
System.out.println("a.hashCode="+a.hashCode()+" "+"p.hashCode="+p.hashCode());
System.out.println("a.toString()="+a.toString());
System.out.println("p.toString()="+p.toString());
/*
未賦值前,兩者的雜湊碼是不相同的:
a.hashCode=366712642 p.hashCode=1829164700
a.toString()[email protected]
p.toString()[email protected]
*/
a=p;
System.out.println("賦值後,兩者的雜湊碼相同:");
System.out.println("a.hashCode="+a.hashCode()+" "+"p.hashCode="+p.hashCode());
System.out.println("a.toString()="+a.toString());
System.out.println("p.toString()="+p.toString());
/*
賦值後,兩者的雜湊碼相同:
a.hashCode=1829164700 p.hashCode=1829164700
a.toString()[email protected]
p.toString()[email protected]
*/
}
}