参考链接:http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452206.html
先查看Java String 的源码
private final char value[];
private int hash; // Default to 0
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;
}
hashCode方法
/**
* 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;
}
计算字符串的hashCode是根据对应字符的ASCII来计算的。
例如字符串:“123”
数字 | ASCII 值 |
1 | 49 |
2 | 50 |
3 | 51 |
计算公式:49*31^2+50*31+51=48690
为什么需要重写equals方法的同时也重写hashCode方法,因为只重写了equals方法但不重写hashCode两个对象相同,但它们的hashCode值不一样,这样将它们放在set集合里,他们是不同的对象,它们的hashCode值不一样。
其次,为什么重写equals方法必须重写hashCode方法,因为这两个方法是有关联的。就像上面的例子都用到了value[]数组。
Object中的equals是比较的值是否相同,用“==”来比较
public boolean equals(Object obj) {
return (this == obj);
}
测试代码:
package com.example.demo;
public class Person {
private Integer id;
private String username;
private Integer age;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Person(Integer id, String username, Integer age) {
this.id = id;
this.username = username;
this.age = age;
}
public int hashCode() {
final int prime = 31;
int result =1;
result = prime * 31 + ((id == null) ? 0 : id.hashCode());
return result;
}
public boolean equals(Object obj) {
if(this == obj) {
return true;
}
if(obj == null) {
return false;
}
if(obj instanceof Person) {
Person person = (Person) obj;
if(id == person.getId() && username.equals(person.getUsername()) && age == person.getAge()) {
return true;
}
return false;
}
return false;
}
@Override
public String toString() {
return "Person [id=" + id + ", username=" + username + ", age=" + age + "]";
}
测试运行:
Person person1 = new Person(1, "Jerry", 28);
Person person2 = new Person(1, "Jerry", 27);
Set<Person> persons = new HashSet<Person>();
persons.add(person1);
persons.add(person2);
System.out.println("person1 equals person2: "+person1.equals(person2)); // false
System.out.println("persons size:"+persons.size()); // 2
System.out.println("person1 hashCode: "+person1.hashCode()); // 962
System.out.println("person2 hashCode: "+person2.hashCode()); // 962
System.out.println("person1 toString:"+person1.toString()); // person1 toString:Person [id=1, username=Jerry, age=28]
System.out.println("person2 toString:"+person2.toString()); // person2 toString:Person [id=1, username=Jerry, age=27]
System.out.println(persons); // [Person [id=1, username=Jerry, age=28], Person [id=1, username=Jerry, age=27]]
Integer a = 1;
System.out.println("1 hashCode: "+ a.hashCode()); // 1 hashCode: 1
String str1 = new String("123");
String str2 = new String("123");
System.out.println(str1 == str2); //false
System.out.println(str1.equals(str2)); //true