Java原始碼之String的HashCode方法
首先看下String類的HashCode原始碼,詳見對應語句後的註釋:
public int hashCode() {
// The hash or hashIsZero fields are subject to a benign data race,
// making it crucial to ensure that any observable result of the
// calculation in this method stays correct under any possible read of
// these fields. Necessary restrictions to allow this to be correct
// without explicit memory fences or similar concurrency primitives is
// that we can ever only write to one of these two fields for a given
// String instance, and that the computation is idempotent and derived
// from immutable state
int h = hash; //String初始化時hash值預設為零
if (h == 0 && !hashIsZero) { //避免重複計算hash值。String物件初始化時,h=hash預設為0,hashIsZero預設為false
h = isLatin1() ? StringLatin1.hashCode(value) //根據字元編碼呼叫不同的計算方法,value是實現String的字元陣列
: StringUTF16.hashCode(value);
if (h == 0) {
hashIsZero = true; //如果計算出的h值為0,則將hashIsZero賦值為true
} else {
hash = h; //計算出的h值不為0時,將h賦值為hash
}
}
return h;
}
下面看下 StringLatin1.hashCode(value)和StringUTF16.hashCode(value)方法的原始碼:
//StringLatin1.hashCode(value)
public static int hashCode(byte[] value) {
int h = 0;
for (byte v : value) {
h = 31 * h + (v & 0xff); //根據字元計算hash值
}
return h;
}
//StringUTF16.hashCode(value)
public static int hashCode(byte[] value) {
int h = 0;
int length = value.length >> 1; //將length值除以2,很少呼叫這個方法
for (int i = 0; i < length; i++) { //根據字元計算hash值
h = 31 * h + getChar(value, i);
}
return h;
}
Latin1是ISO-8859-1編碼的別名,大家可以看到hash值是根據“h = 31 * h + ASCII碼”遞迴所有字元陣列求得,下面舉個簡單的例子:
public class StringHashCode {
public static void main(String[] args){
System.out.println("編碼方式:"+Charset.defaultCharset().name());
String s1 = "a";
String s2 = "s";
String s3 = "as";
System.out.println("a的hashCode:"+s1.hashCode());
System.out.println("s的hashCode:"+s2.hashCode());
System.out.println("as的hashCode:"+s3.hashCode());
}
}
結果為:
如有錯誤,敬請指正
相關文章
- String的equals和hashCode方法
- String中hashCode方法的執行緒安全執行緒
- Java String原始碼分析Java原始碼
- hashCode()方法原始碼執行簡要分析原始碼
- Java-- String原始碼分析Java原始碼
- 死啃了String原始碼之後原始碼
- 搞懂 Java equals 和 hashCode 方法Java
- java基礎:String — 原始碼分析(一)Java原始碼
- Java基礎系列-equals方法和hashCode方法Java
- String,String Builder,String Buffer-原始碼UI原始碼
- JDK原始碼解析系列之String 之一JDK原始碼
- java中的hashCodeJava
- Java原始碼閱讀-String中的private final char value[];Java原始碼
- String原始碼分析原始碼
- 面試之Java String 編碼相關面試Java
- Java中String類的常用方法Java
- Java hashCode() 指南Java
- String原始碼淺析原始碼
- Java-String的常用方法總結!Java
- 原始碼|String拼接操作”+”的優化?原始碼優化
- java原始碼 - ReentrantLock之FairSyncJava原始碼ReentrantLockAI
- java原始碼-ReentrantLock之FairSyncJava原始碼ReentrantLockAI
- java原始碼-ReentrantLock之NonfairSyncJava原始碼ReentrantLockAI
- js原生api之String的slice方法JSAPI
- [Java基礎]HashcodeJava
- String 原始碼淺析(一)原始碼
- java為什麼要重寫hashCode和equals方法Java
- Java原始碼分析:Guava之不可變集合ImmutableMap的原始碼分析Java原始碼Guava
- Spring原始碼之六-onRefresh()方法Spring原始碼
- Java集合之Hashtable原始碼解析Java原始碼
- Java集合之ArrayList原始碼解析Java原始碼
- Java集合之LinkedList原始碼解析Java原始碼
- Java讀原始碼之ReentrantLock(2)Java原始碼ReentrantLock
- java併發之hashmap原始碼JavaHashMap原始碼
- 【Java】NIO中Selector的select方法原始碼分析Java原始碼
- 【原始碼閱讀】Glide原始碼閱讀之with方法(一)原始碼IDE
- 【原始碼閱讀】Glide原始碼閱讀之into方法(三)原始碼IDE
- Java之String的equals與contentEquals區別Java