直接看代码,为什么我直接添加一个String对象contains()返回的是true,添加一个Dog对象的时候就返回false,还有Set不是不能添加一个重复元素,为什么Dog对象可以添加两个,String对象则不能
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>();
boolean resultq;
dogSet.add(new Dog("we have white"));
System.out.println("We have " + dogSet.size() + " white dogs!");
resultq = dogSet.contains(new Dog("we have white"));
System.out.println(resultq);
HashSet<String> books = new HashSet<String>();
//添加一个字符串对象
books.add(new String("Struts2权威指南"));
books.add(new String("Struts2权威指南"));
boolean result = books.contains(new String("Struts2权威指南"));
System.out.println("We have " + books.size() + " books!");
System.out.println(result);
//下面输出看到集合只有一个元素
System.out.println(books);
}
}
执行结果是:
**We have 2 white dogs!
false
We have 1 books!
true
[Struts2权威指南]**
这个问题直接看源码。contains源码使用的是HashMap的getNdoe方法
判断是否包含另一个对象要同时满足hash相等和内存中是否是同一个对象或者equals方法是否相等。
String对象已经重写了hashCode和equals方法,只要String的value相等,即返回的hashcode相等,equals返回true.
Dog对象没有写hashCode和equals方法,使用的是父类Object的方法,创建不同的对象的hashcode不同,equals返回false,所以不会满足上图源码的if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))条件,所以可以使用color属性重写hashcode和equals方法,调用contains返回true