Java HashMap containsKey为现有对象返回false
我有一个用于存储对象的HashMap:
private Map<T, U> fields = Collections.synchronizedMap(new HashMap<T, U>());
但是,当尝试检查键是否存在时,containsKey
方法会返回false
。
equals
和hashCode
方法已实现,但未找到密钥。
调试一段代码时:
return fields.containsKey(bean) && fields.get(bean).isChecked();
我有:
bean.hashCode() = 1979946475 fields.keySet().iterator().next().hashCode() = 1979946475
bean.equals(fields.keySet().iterator().next())= true
fields.keySet().iterator().next().equals(bean) = true
但
fields.containsKey(bean) = false
是什么原因导致这种奇怪的行为?
public class Address extends DtoImpl<Long, Long> implements Serializable{ <fields>
<getters and setters>
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + StringUtils.trimToEmpty(street).hashCode();
result = prime * result + StringUtils.trimToEmpty(town).hashCode();
result = prime * result + StringUtils.trimToEmpty(code).hashCode();
result = prime * result + ((country == null) ? 0 : country.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Address other = (Address) obj;
if (!StringUtils.trimToEmpty(street).equals(StringUtils.trimToEmpty(other.getStreet())))
return false;
if (!StringUtils.trimToEmpty(town).equals(StringUtils.trimToEmpty(other.getTown())))
return false;
if (!StringUtils.trimToEmpty(code).equals(StringUtils.trimToEmpty(other.getCode())))
return false;
if (country == null) {
if (other.country != null)
return false;
} else if (!country.equals(other.country))
return false;
return true;
}
}
回答:
将密钥插入地图后,您不得对其进行修改。
编辑:我在Map中找到了javadoc的摘录:
注意:如果将可变对象用作地图键,则必须格外小心。如果在对象是映射中的键的情况下以影响等值比较的方式更改对象的值,则不会指定映射的行为。
一个简单的包装器类的示例:
public static class MyWrapper { private int i;
public MyWrapper(int i) {
this.i = i;
}
public void setI(int i) {
this.i = i;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
return i == ((MyWrapper) o).i;
}
@Override
public int hashCode() {
return i;
}
}
和测试:
public static void main(String[] args) throws Exception { Map<MyWrapper, String> map = new HashMap<MyWrapper, String>();
MyWrapper wrapper = new MyWrapper(1);
map.put(wrapper, "hello");
System.out.println(map.containsKey(wrapper));
wrapper.setI(2);
System.out.println(map.containsKey(wrapper));
}
输出:
truefalse
注意:如果您不重写hashcode(),那么您只会得到true
以上是 Java HashMap containsKey为现有对象返回false 的全部内容, 来源链接: utcz.com/qa/408323.html