为啥调用congtainsKey()的时候没有出现错误???
如果key是自定义类型,那就要重写equals方法,而且还要重写hashcode方法。这边的String类型已经重写了hashcode方法和equals方法。自定义的类型都要重写equals。至于要不要重写hashCode,看你是否实现的hash的接口,或者你继承的父类是不是实现了,不是,不用重写。是就要重写。
要重写hashCode方法主要是源码里调用了hash方法的。
Hashmap;可以看见containsKey有hash
public boolean containsKey(Object key) { return getNode(hash(key), key) != null; }
public synchronized boolean contains(Object value) { if (value == null) { throw new NullPointerException(); } Entry<?,?> tab[] = table; for (int i = tab.length ; i-- > 0 ;) { for (Entry<?,?> e = tab[i] ; e != null ; e = e.next) { if (e.value.equals(value)) { return true; } } } return false; }
HashSet:也有hash方法
public boolean containsKey(Object key) { return getNode(hash(key), key) != null; }
ArrayList;并没有调用hash方法,indexOf同样也没有调用
public boolean contains(Object o) { return indexOf(o) >= 0; }
凑巧Key是String类型的,String重写过了equals
contains() 和 containsKey()都会调用equals()方法
参数为String类型的equals方法和以对象为类型的equals方法不同。
equals(String key)会同时比较地址和内容,其中一个为true的时候返回true。
equals (Object value)只会比较地址是否相同,地址相同的时候返回true。
因此要重写equals方法之后才能使用containsKey方法(否则只会比较地址,而不会比较学生姓名)。containsKey由于参数是String,所有默认的equals就会比较值和地址,就不需要重写了。
containsKey()和containsValue()都调用了equals()方法进行比较,但是这个题目中的key是String类型的,String类型的equals()比较的是字符串的内容,所以我们根据键去查找学生的结果是true;但是Value是Student类型的,equals()比较的是对象的引用地址,所以返回结果是false。那么就需要重写equals()方法。