一、hashCode函数
public int hashCode() { int h = hash; if (h == 0 && value.length > 0) { char val[] = value; for (int i = 0; i < value.length; i++) { h = 31 * h + val[i]; } hash = h; } return h; }
- hashCode()对字符串的哈希值是做了缓存的,第一次会创建哈希值,往后的则将使用缓存中的值。
- 使用的计算方法为:s[0]*31(n-1)+s[1]*31(n-2)+....+s[n-1]
- 使用31作为基数
- 31 * i = 32 * i - i = (i<<5) - i 通过移位和减法运算,有助于提高运算速度。
- 31是质数
- 一个对象如果存储在散列集合内,需要复写hashCode,因为散列集合存储对象是根据hashCode的值(相当于地址)进行存储。
- 从函数的实现可以得到一个转换成10进制的工具:
public static int calculate(int radix, int[] a) { int sum = 0; for (int i = 0; i < a.length; i++) { sum = sum * radix + a[i]; } return sum; }
二、equals函数
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }
- 重写equals要遵守以下特征:
- 自反性:对于任何非null的引用值x, x.equals(x)必须返回true。
- 对称性:对于任何非null的引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)必须返回true
- 传递性:对于任何非null的引用值x,y和z,如果x.equals(y)返回true,并且y.equals(z)返回true,那么x.equals(z)返回true
- 对于任何非null的引用值x和y,只要equals的比较操作在对象中所用的信息没有被修改,多次调用x.equals(y)就会一致地返回true,或者一致地返回false
- 对于任何非null的引用值x,x.equals(null)必须返回false
- 运行流程:
- 先判断是否自身对象
- 再判断是否是String类实例(子类也算)
- 再判断字符串长度
- 最后判断对比每个字符