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中的HashCode和EqualJava
- Java String原始碼分析Java原始碼
- String中hashCode方法的執行緒安全執行緒
- hashCode()方法原始碼執行簡要分析原始碼
- Java-- String原始碼分析Java原始碼
- Java Object 之hashCodeJavaObject
- Java 原始碼分析 — String 的設計Java原始碼
- 死啃了String原始碼之後原始碼
- 搞懂 Java equals 和 hashCode 方法Java
- Java hashCode() 方法深入理解Java
- java基礎:String — 原始碼分析(一)Java原始碼
- 解析java語言中String方法之indexOfJavaIndex
- Java -- String的intern方法Java
- Java基礎系列-equals方法和hashCode方法Java
- JDK原始碼解析系列之String 之一JDK原始碼
- 面試之Java String 編碼相關面試Java
- 如何正確實現Java中的hashCode方法Java
- 常見物件-String類的compareTo()方法的原始碼解析物件原始碼
- String,String Builder,String Buffer-原始碼UI原始碼
- java中的hashCodeJava
- Java String類的replaceAll方法Java
- java String的equals,intern方法Java
- String原始碼分析原始碼
- Java原始碼閱讀-String中的private final char value[];Java原始碼
- Java中String類的常用方法Java
- Java 中 String 的構造方法Java構造方法
- Java 中 String 的常用方法(一)Java
- Java 中 String 的常用方法(二)Java
- String原始碼淺析原始碼
- java String 常用方法集合Java
- Java之所有物件的公用方法>9.Always override hashCode when you override equalsJava物件IDE
- Java hashCode() 指南Java
- StringBuilder StringBuffer String的區別(原始碼分析)-javaUI原始碼Java
- Java原始碼分析:Guava之不可變集合ImmutableMap的原始碼分析Java原始碼Guava
- jQuery原始碼分析之tokenize()方法jQuery原始碼
- jQuery原始碼分析之Sizzle方法jQuery原始碼