1. 程式人生 > >Java學習筆記15:java中的hashcode雜湊碼、hash 演算法

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中,雜湊碼代表了物件的一種特徵,例如我們判斷某兩個字串是否==,如果其雜湊碼相等,則這兩個字串是相等的。

其次,雜湊碼是一種資料結構的演算法。

常見的雜湊碼的演算法有:

  1. Object類的hashCode.返回物件的記憶體地址經過處理後的結構,由於每個物件的記憶體地址都不一樣,所以雜湊碼也不一樣。

  2. String類的hashCode.根據String類包含的字串的內容,根據一種特殊演算法返回雜湊碼,只要字串內容相同,返回的雜湊碼也相同。

  3. 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]
         */
    }
}