【问题标题】:Why doesn't ConcurrentHashMap return the value even though key.equals(k)?为什么即使 key.equals(k) ConcurrentHashMap 也不返回值?
【发布时间】:2014-11-04 18:55:39
【问题描述】:

我有一个简单的对象,我想在我的 HashMap 中用作键。 MyObject 的定义如下:

MyObject obj1 = new MyObject("some string");
MyObject obj2 = new MyObject("some string");
assertTrue(obj1.equals(obj2));
assertTrue(obj1.hashCode()==obj2.hashCode());

根据ConcurrentHashMap.get 的文档,

如果此映射包含从键 k 到值 v 的映射,使得 key.equals(k), 然后这个方法返回 v;否则返回 null

但是,如果我尝试使用 MyObject 作为映射键,则检索失败:

ConcurrentHashMap<MyObject,String> map = new ConcurrentHashMap<MyObject,String>();
map.put(obj1,"test value");
String foundValue = map.get(obj2);
assertNotNull(foundValue);         //fails

我错过了什么?


编辑:根据要求,这是一个完整的运行示例:

import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

public class MyObject {
    String name = null;

    public MyObject(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public boolean equals(MyObject otherObject) {
        boolean result = false;
        if (otherObject!=null) {
            if (getClass().equals(otherObject.getClass())) {
                if (name==null) {
                    if (otherObject.getName()==null)
                        result = true;
                } else if (name.equals(otherObject.getName()))
                    result = true;
            }
        }
        return result;
    }

    public int hashCode() {
        return Objects.hash(name);
    }

    public static void main(String[] args) {
        MyObject obj1 = new MyObject("some string");
        MyObject obj2 = new MyObject("some string");
        if (obj1.equals(obj2) && obj1.hashCode()==obj2.hashCode()) {
            ConcurrentHashMap<MyObject,String> map = new ConcurrentHashMap<MyObject,String>();
            map.put(obj1,"test value");
            String foundValue = map.get(obj2);
            if (foundValue==null)
                System.out.println("get returned null");
            else
                System.out.println("get returned my string");
        } else {
            System.out.println("something's not equal");
        }
    }
}

【问题讨论】:

  • @markspace 是的。我更新了问题以反映这一点。
  • 你必须显示来自MyObject 的代码。 HashMap 有效,问题一定出在其他地方。向我们展示你创建的 equals 和 hashCode 方法。
  • 尝试用 name.hashCode() 替换 Objects.hash(name)。来自文档:警告:提供单个对象引用时,返回的值不等于该对象引用的哈希码。这个值可以通过调用 hashCode(Object) 来计算。
  • @cecil23 如果我这样做,我需要检查是否为空。 Objects.hash() 应该解决这个问题。无论如何,我改变了它,结果是一样的。

标签: java


【解决方案1】:

您尚未覆盖 equals,而是创建了一个具有不同签名的新 equals 方法。

如果你改变了

public boolean equals(MyObject otherObject) {

public boolean equals(Object otherObject) {

(并添加适当的强制转换),您的代码将按预期工作。

您可以通过使用@Override 注释轻松避免该错误,这会导致编译错误。

【讨论】:

  • 我实现了hashCode,两个对象的hashCode相等
  • @datguy 你能展示一个完整的例子来编译和重现你的问题吗?魔鬼往往在细节中......
  • 那是一个可怕的小细节。在转换之前,我假设我应该检查以确保它是 MyObject 的一个实例,对吗?
  • @datguy 是,否则返回 false。
猜你喜欢
  • 2020-07-21
  • 2022-07-12
  • 2019-10-25
  • 1970-01-01
  • 2019-10-03
  • 2012-06-13
  • 2021-08-15
  • 1970-01-01
  • 2019-04-03
相关资源
最近更新 更多