1. 程式人生 > >(考研)散列表和hashcode和hashmap

(考研)散列表和hashcode和hashmap

兩個 code 作用 equal hash算法 too println 內容 import

package tt;

import java.util.HashMap;
import java.util.Map;

public class a0 {
    public static void main(String[] args){
        
        /**
         * 如果兩個對象相同,那麽這兩個對象的hashCode一定要相同
String a1 ="abc"   String a2 ="abc" 這a1和a2就是相同的對象 * * 兩個對象的hashCode相同,並不一定表示兩個對象就相同,他們“存放在同一個籃子裏”
      String s1 = new String("abc") String s2 = new String("abc") * * 驗證:只要2個對象的內容是同的返回hashCode是相同的 * 那麽在兩個對象中的每個對象上調用 hashCode 方法都必須生成相同的整數結果。
*/ Integer i1 = 100; Integer i2=Integer.valueOf(100); String s1="a"; String s2="a"; //實質會執行如下的代碼 Integer i1 = Integer.valueOf(100),上面的2句話是等效的 //若int值在[-128,-127]之間的話,會返回緩沖池的數據,否的 return new Integer(i) System.out.println(i1==i2);//true System.out.println(s1==s2);//true
System.out.println("code"+i1.hashCode()+","+i2.hashCode()+";"+s1.hashCode()+","+s2.hashCode()); //code100,100;97,97 //Integer 變量名; 若值在[-128,-127]之間,變量名都是指向同一對象 //String str="abc" 只要後面的值都相同,多個變量名指向同一個“abc”
Integer i3
= new Integer(100); String ss = new
String("a"); System.out.println(i1==i3);//flase System.out.println(s2== ss);//false System.out.println("code"+i1.hashCode()+","+i3.hashCode()+";"+s2.hashCode()+","+ss.hashCode()); //code100,100;97,97 Integer in = new Integer(100); Integer in1 = new Integer(100); String abc = "abcd"; String abc1="abcd"; System.out.println("code"+in.hashCode()+","+in1.hashCode()+";"+abc.hashCode()+","+abc1.hashCode()); //code100,100;2987074,2987074 //對象肯定不同的,但是內容是同的 String str1 = "name"; String str2 = new String("name"); System.out.println(str1==str2);//false System.out.println(str1.hashCode() +" "+ str2.hashCode());//3373707 3373707 Map<String,String> map =new HashMap<String,String>(); /* 如果key在鏈表中已存在,則替換為新value*/ * 對象equals 是true的話,hashCode需要相同,但是hashCode相同的對象不一定equals,這就是所謂的沖突現象,但是有不同的沖突解決方法。你的hashCode()設計的好的話沖突也就小了。比如樓上給出的超出int範圍之後這種hashCode()實現,對象肯定是無數的,但是hash實現是有限的呢,所以沖突了 */ map.put(str1,"Tom"); map.put(str2, "Lisa"); System.out.println(map); //輸出 name = "Lisa" //你構造不出 key1 和 key2 對象不同,但是他們的hashcode相同 } }

HashMap實際上是一個“鏈表散列”的數據結構,即數組和鏈表的結合體。

技術分享技術分享

Put操作:

如果兩個key通過hash%Entry[].length得到的index相同,會不會有覆蓋的危險?

  這裏HashMap裏面用到鏈式數據結構的一個概念。上面我們提到過Entry類裏面有一個next屬性,作用是指向下一個Entry。打個比方, 第一個鍵值對A進來,通過計算其key的hash得到的index=0,記做:Entry[0] = A。一會後又進來一個鍵值對B,通過計算其index也等於0,現在怎麽辦?HashMap會這樣做:B.next = A,Entry[0] = B,如果又進來C,index也等於0,那麽C.next = B,Entry[0] = C;這樣我們發現index=0的地方其實存取了A,B,C三個鍵值對,他們通過next這個屬性鏈接在一起

當我們往HashMap中put元素的時候,先根據key的重新計算元素的hashCode,根據hashCode得到這個元素在table數組中的位置(即下標),如果數組該位置上已經存放有其他元素了,那麽在這個位置上的元素將以鏈表的形式存放,新加入的放在鏈頭,最先加入的放在鏈尾。如果數組該位置上沒有元素,就直接將該元素放到此數組中的該位置上

get操作(先hashcode方法再equals方法)

有了上面存儲時的hash算法作為基礎,理解起來這段代碼就很容易了。從上面的源代碼中可以看出:從HashMap中get元素時,首先計算key的hashCode,找到數組中對應位置的某一元素,然後通過key的equals方法在對應位置的鏈表中找到需要的元素。

(考研)散列表和hashcode和hashmap