java中的hashCode计算方法总结
Object.hashCode()
该方法为native修饰,没有java实现
根据对象的地址转换为整数来实现
类重写hashCode()方法
String 重写hashCode()
string就是字符数组char[]
string的属性 value 就是字符数组
private final char value[];
计算方法:
s[0]*31^(n-1) + s[1]*31^(n-2) + … + s[n-1]
n为字符串长度,s[i]是第i个字符
hash是string的属性,初始化hash = 0
/**
* Returns a hash code for this string. The hash code for a
* {@code String} object is computed as
* <blockquote><pre>
* s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
* </pre></blockquote>
* using {@code int} arithmetic, where {@code s[i]} is the
* <i>i</i>th character of the string, {@code n} is the length of
* the string, and {@code ^} indicates exponentiation.
* (The hash value of the empty string is zero.)
*
* @return a hash code value for this object.
*/
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;
}
System.out.println("a".hashCode()); // 97
System.out.println("ab".hashCode()); //3105
System.out.println(31*97+98); //3105
自定义类重写hashCode()
Student 类,类的hashCode为 31 * (name的hashCode) + (age的hashCode)
public class Student {
public String name;
public int age;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
if (age != student.age) return false;
return name != null ? name.equals(student.name) : student.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0; //先获得name的hashCode,若name是null,则为0,否则调用String,hashCode()
result = 31 * result + age; //age是int类型,hashCode就是自身
return result;
}
还有一种写法, 调用Objects.hash()
@Override
public int hashCode() {
return Objects.hash(name, age);
}
继续跟进,,调用 Arrays.hashCode()
//Objects 类 Objects.hash方法
public static int hash(Object... values) {
return Arrays.hashCode(values);
}
跟进,和上述计算hashCode方法一样,将参数数组遍历,若参数为null,则为0, 否则取值hashCode,和字符串计算hasCode相似
//Arrays类, Arrays.hashCode方法
public static int hashCode(Object a[]) {
if (a == null)
return 0;
int result = 1;
for (Object element : a)
result = 31 * result + (element == null ? 0 : element.hashCode());
return result;
}