參考連接:http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452206.html html
先查看Java String 的源碼java
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方法 ide
/** * 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」this
數字 | ASCII 值 |
1 | 49 |
2 | 50 |
3 | 51 |
計算公式:49*31^2+50*31+51=48690spa
爲何須要重寫equals方法的同時也重寫hashCode方法,由於只重寫了equals方法但不重寫hashCode兩個對象相同,但它們的hashCode值不同,這樣將它們放在set集合裏,他們是不一樣的對象,它們的hashCode值不同。code
其次,爲何重寫equals方法必須重寫hashCode方法,由於這兩個方法是有關聯的。就像上面的例子都用到了value[]數組。htm
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