import java.util.HashSet; class Dog{ String color; public Dog(String s){ color = s; } } public class SetAndHashCode { public static void main(String[] args) { HashSet<Dog> dogSet = new HashSet<Dog>(); dogSet.add(new Dog("white")); dogSet.add(new Dog("white")); System.out.println("We have " + dogSet.size() + " white dogs!"); if(dogSet.contains(new Dog("white"))){ System.out.println("We have a white dog!"); }else{ System.out.println("No white dog!"); } } }
We have 2 white dogs! No white dog!
HashSet<Dog> a = new HashSet<Dog>(); a.add(null); if(a.contains(null)){ System.out.println("true"); }
class Dog{ String color; public Dog(String s){ color = s; } //重写equals方法, 最佳实践就是如下这种判断顺序: public boolean equals(Object obj) { if (!(obj instanceof Dog)) return false; if (obj == this) return true; return this.color == ((Dog) obj).color; } }英文答案是: no.
class Dog{ String color; public Dog(String s){ color = s; } //重写equals方法, 最佳实践就是如下这种判断顺序: public boolean equals(Object obj) { if (!(obj instanceof Dog)) return false; if (obj == this) return true; return this.color == ((Dog) obj).color; } public int hashCode(){ return color.length();//简单原则 } }
import java.util.HashSet; import java.util.Set; public class TestContains { public static final class Person{ private String name = ""; public Person(String n) { setName(n); } public String getName() { return name; } public void setName(String name) { this.name = (name==null)? "" : name; } @Override public int hashCode() { // 请考虑是否值得这么做,因为此时name是会变的. return name.length(); // 推荐让name不可改变 } @Override public boolean equals(Object obj) { if(!(obj instanceof Person)){ return false; } if(obj == this){ return true; } return this.name.equals(((Person)obj).name); } }; public static void main(String[] args) { Set<Person> persons = new HashSet<Person>(); // Person person = new Person("tiemao"); persons.add(person); // 修改name, 则依赖hash的集合可能失去作用 person.setName("ren"); // 同一个对象,居然是false,原因是我们重写了hashCode,打破了hashCode不变的基本约定 boolean has = persons.contains(person); int size = persons.size(); System.out.println("has="+has); // has=false. System.out.println("size="+size);// size=1 } }
1. Java equals() and hashCode() Contract
2. HashMap vs. TreeMap vs. Hashtable vs. LinkedHashMap
3. Java: Find all callers of a method – get all methods that call a particular method
4. 理解Java机制最受欢迎的8幅图