自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java HashMap分析之二:Hash code

開發(fā) 后端
散列計(jì)算就是計(jì)算元素應(yīng)該放在數(shù)組的哪個(gè)元素里。準(zhǔn)確的說(shuō)是放到哪個(gè)鏈表里面。按照J(rèn)ava的規(guī)則,如果你要想將一個(gè)對(duì)象放入HashMap中,你的對(duì)象的類必須提供hashcode方法,返回一個(gè)整數(shù)值。

散列計(jì)算就是計(jì)算元素應(yīng)該放在數(shù)組的哪個(gè)元素里。準(zhǔn)確的說(shuō)是放到哪個(gè)鏈表里面。按照J(rèn)ava的規(guī)則,如果你要想將一個(gè)對(duì)象放入HashMap中,你的對(duì)象的類必須提供hashcode方法,返回一個(gè)整數(shù)值。比如String類就有如下方法:

  1. public int hashCode() {  
  2.         int h = hash;  
  3.         int len = count;  
  4.         if (h == 0 && len > 0) {  
  5.             int off = offset;  
  6.             char val[] = value;  
  7.  
  8.             for (int i = 0; i < len; i++) {  
  9.                 h = 31*h + val[off++];  
  10.             }  
  11.             hash = h;  
  12.         }  
  13.         return h;  
  14.     } 

注意上面的for循環(huán),有點(diǎn)搞吧?我來(lái)舉個(gè)例子,讓你很容易明白它在搞什么名堂。比如有一個(gè)字符串“abcde”,采用31進(jìn)制的計(jì)算方法來(lái)計(jì)算這個(gè)字符串的總和,你會(huì)寫出下面的計(jì)算式子:
a*31^4+b*31^3+c*31^2+d*31^1+e*31^0.注意,這里的a,b,c,d或者e指的是它們的ASCII值。很有趣的循環(huán),居然可以用來(lái)算N進(jìn)制。這個(gè)循環(huán)可以抽出來(lái)單獨(dú)作為計(jì)算進(jìn)制的好工具:

  1. public static void main(String[] args) {  
  2.         int[] a={1,0};  
  3.         System.out.println(calculate(2,a));  
  4.     }  
  5.  
  6.     private static int calculate(int radix,int[] a){  
  7.         int sum = 0;  
  8.         for(int i=0;i<a.length;++i){  
  9.             sum = sum*radix+a[i];  
  10.         }  
  11.         return sum;  
  12.     } 

靜態(tài)方法caculate接受radix作為進(jìn)制基數(shù),數(shù)組a模擬要計(jì)算的進(jìn)制的數(shù)字,只是注意表面順序需要一致。比如 01 二進(jìn)制串,在數(shù)組中要按照{(diào)0,1}排列。上面的輸出結(jié)果是1,符合01的真實(shí)值。

那么為什么選用31作為基數(shù)呢?先要明白為什么需要HashCode.每個(gè)對(duì)象根據(jù)值計(jì)算HashCode,這個(gè)code大小雖然不奢求必須唯一(因?yàn)檫@樣通常計(jì)算會(huì)非常慢),但是要盡可能的不要重復(fù),因此基數(shù)要盡量的大。另外,31*N可以被編譯器優(yōu)化為

左移5位后減1,有較高的性能。其實(shí)選用31還是有爭(zhēng)議,反對(duì)者(參考http://stackoverflow.com/questions/299304/why-does-javas-hashcode-in-string-use-31-as-a-multiplier
認(rèn)為這個(gè)東西還是會(huì)導(dǎo)致較多的重復(fù),應(yīng)該用更大的數(shù)字。所以,或許將來(lái)Java的實(shí)現(xiàn)中會(huì)有所變化。下面這篇文章介紹了兩個(gè)結(jié)論:

1.基數(shù)要用質(zhì)數(shù)

質(zhì)數(shù)的特性(只有1和自己是因子)能夠使得它和其他數(shù)相乘后得到的結(jié)果比其他方式更容易產(chǎn)成唯一性,也就是hash code值的沖突概率最小。

2.選擇31是觀測(cè)分布結(jié)果后的一個(gè)選擇,不清楚原因,但的確有利。

http://computinglife.wordpress.com/2008/11/20/why-do-hash-functions-use-prime-numbers/

另外,String.hashCode內(nèi)部會(huì)緩存第一次計(jì)算的值,因?yàn)檫@是一個(gè)final(不可變)類,也就是String對(duì)象的內(nèi)容是不會(huì)變的。這能夠在多次put到HashMap的場(chǎng)合提高性能,不過(guò)似乎用處不多。

好了,終于扯完了String.hashCode的話題。現(xiàn)在繼續(xù)回到HashMap的數(shù)組元素位置計(jì)算上來(lái)。

 

原文鏈接:http://blog.csdn.net/sheismylife/article/details/7351005

【編輯推薦】

  1. Java HashMap分析之一:基本結(jié)構(gòu)
  2. Java集合框架總結(jié):Set接口的使用
  3. Java的位移運(yùn)算巧方法
  4. Java7的一個(gè)新類JLayer:裝飾的Swing組件
  5. 關(guān)于Java中內(nèi)存溢出的解決辦法
責(zé)任編輯:林師授 來(lái)源: sheismylife的博客
相關(guān)推薦

2015-08-10 15:12:27

Java實(shí)例源碼分析

2021-09-10 06:50:03

HashMapHash方法

2023-02-13 08:01:49

HashHashMapint

2016-09-12 14:33:20

javaHashMap

2012-03-15 17:18:33

JavaHashMap

2012-03-15 16:12:57

JavaHashMap

2018-04-19 14:11:50

2012-02-15 10:34:29

JavaJava Socket

2021-11-08 15:06:15

鴻蒙HarmonyOS應(yīng)用

2011-05-27 14:03:22

網(wǎng)站流量

2022-03-04 15:43:36

文件管理模塊Harmony鴻蒙

2022-05-09 11:52:38

Java卡片服務(wù)卡片

2021-10-11 11:58:41

Channel原理recvq

2021-12-01 07:02:16

虛擬化LinuxCPU

2021-02-15 15:36:20

Vue框架數(shù)組

2021-01-18 05:33:08

機(jī)器學(xué)習(xí)前端算法

2021-12-17 07:47:37

TCASwiftUI 運(yùn)作

2020-10-15 14:10:51

網(wǎng)絡(luò)攻擊溯源

2021-06-29 08:28:12

算法順序表數(shù)據(jù)

2021-10-28 19:27:08

C++指針內(nèi)存
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)