假设一个map里放有两个不同的对象,但这两个对象某些属性相同,从程序员的逻辑角度上来看可以认为是相同的。那该如何做呢?
一. 源码
首先来看HashMap.getEntry()的源码
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 && key.equals(k))))
return e;
}
return null;
}
二. 分析
从getEntry()可以看出,判断时会遍历map中所有的entry,当以下两个条件都满足时才会判断相等:- hash值一样;
- key为同一个对象,或两个key使用其equals()方法比较时相等。
因此在使用map.get(key)时
- 要么key为同一个对象;
- 要么key类要有自己的public int hashCode()及public boolean equals(Object obj)方法,使其相等。
三. 示例
@Test
public void get() {
Person person1 = new Person(1, "test");
Map<Person, String> map = new HashMap<Person, String>();
map.put(person1, "hello,world");
logger.debug(map.get(new Person(1, "test")));
}
class Person {
private int id;
private String name;
public Person(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj instanceof Person) {
return (this.id == ((Person) obj).id)
&& (this.name.equals(((Person) obj).name));
}
return false;
}
public int hashCode() {
return this.toString().hashCode();
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + "]";
}
}