Java HashMap containsKey为现有对象返回false

我有一个用于存储对象的HashMap:

    private Map<T, U> fields = Collections.synchronizedMap(new HashMap<T, U>());

但是,当尝试检查键是否存在时,containsKey方法会返回false

equalshashCode方法已实现,但未找到密钥。

调试一段代码时:

    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));

}

输出:

true

false

注意:如果您不重写hashcode(),那么您只会得到true

以上是 Java HashMap containsKey为现有对象返回false 的全部内容, 来源链接: utcz.com/qa/408323.html

回到顶部