今天看到这样一个问题:
/**补充完该类,不修改main方法,使得get()方法可以取到值*/
package test;
import java.util.HashMap;
import java.util.Map;
public class StudentTest {
private static final class Student {
private static String name;
public Student(String name) {
this.name = name;
}
}
public static void main(String[] args) {
Map p = new HashMap();
p.put(new Student("lily"), "sister");
System.out.println(p.get("lily"));
System.out.print(p.keySet().iterator().next());
}
}
来源: <http://xtwxgh.iteye.com/blog/78459>
测试发现重写student的hashcode也不能重现,本以为hashmap只通过hash后的index作为寻找value的策略,结果还是不行
看源码get方法发现下面,
static class Entry<K,V> implements Map.Entry<K,V> {
final K key;
V value;
Entry<K,V> next;
int hash;
/**
* Creates new entry.
*/
Entry(int h, K k, V v, Entry<K,V> n) {
value = v;
next = n;
key = k;
hash = h;
}
key除了通过hash比较,还要比较本身key和查询key,下面的代码展示Entry除了要记录hash还要记录hash时的Key(object类型)
final Entry<K,V> getEntry(Object key) {
if (size == 0) {
return null;
}
int hash = (key == null) ? 0 : hash(key);
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && )))
return e;
}
return null;
}
总结:
对于hashcode,一般是不推荐重写的,而hashcode本身也是为了对于hashmap这类需要使用hash算法的对象而产生的,如果非要按照自己的需求去实现key,value映射,必须要修改Hashmap中的get等方法,单纯修改key的hashcode算法是不够