Java - map.get 不起作用,但元素在 map 中?

标签 java hashmap equals

所以...一切都在代码中:

// get vector...
SignVector v = ...;

//print to console: [1058, 5, 820 in flat]
System.out.println(v);

//size: 1
System.out.println("size: " + signs.size());

//check all elements...
for (Entry<SignVector, FakeSign> entry : signs.entrySet())
{
    // get key
    SignVector key = entry.getKey();

    //print to console: [1058, 5, 820 in flat] (YaY! it's that key! like v)
    System.out.println(key);
    if (key.equals(v))
    {
        // print: "YaY: " 
        System.out.println("YaY: [1058, 5, 820 in flat]"+key);
    }
}
//So second test... just get it from map: null
System.out.println(signs.get(v));

为什么返回 null?
在JavaDocs中写道:map.get使用key.equals(k)那么为什么我的代码返回好的对象,但是 map.get返回空值?

map : private final Map<SignVector, FakeSign> signs = new HashMap<>()



等于方法形式SignVector对于@home用户

@Override
public boolean equals(Object obj)
{
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    SignVector other = (SignVector) obj;
    // w can't be null so I skip that
    System.out.print(w.getName() + ", " + other.w.getName() + ", " + (w.getName().equals(other.w.getName()))); // this same
    if (!w.getName().equals(other.w.getName()))
        return false;
    if (x != other.x)
        return false;
    if (y != other.y)
        return false;
    if (z != other.z)
        return false;
    return true;
}

但是这个方法效果很好,总是返回我想要的,x , y , zint ,和w是自定义对象。

最佳答案

javadoc 有点误导,但它依赖于这样一个事实:如果您实现 equals,您还应该实现 hashcode 以保持一致。正如文档所述:

Many methods in Collections Framework interfaces are defined in terms of the equals method. For example, the specification for the containsKey(Object key) method says: "returns true if and only if this map contains a mapping for a key k such that (key==null ? k==null : key.equals(k))."

This specification should not be construed to imply that invoking Map.containsKey with a non-null argument key will cause key.equals(k) to be invoked for any key k.

Implementations are free to implement optimizations whereby the equals invocation is avoided, for example, by first comparing the hash codes of the two keys. (The Object.hashCode() specification guarantees that two objects with unequal hash codes cannot be equal.)

More generally, implementations of the various Collections Framework interfaces are free to take advantage of the specified behavior of underlying Object methods wherever the implementor deems it appropriate.

让我们看一下 HashMapget 的底层实现。

314  public V get(Object key) {
315      if (key == null)
316          return getForNullKey();
317      int hash = hash(key.hashCode());
318      for (Entry<K,V> e = table[indexFor(hash, table.length)];
319           e != null;
320           e = e.next) {
321          Object k;
322          if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
323              return e.value;
324      }
325      return null;
326  }

您会看到,它使用对象的哈希码来查找表中可能的条目,然后使用 equals 来确定必须返回哪个值。由于该条目可能为 null,因此会跳过 for 循环并且 get 返回 null

重写 SignVector 类中的 hashCode 以与 equals 保持一致,一切都应该正常工作。

关于Java - map.get 不起作用,但元素在 map 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23409358/

相关文章:

java - Kotlin找不到符号Function1构建错误

Java,如何将值添加到用作 HashMap 中的值的数组列表

java - 为什么创建 HashMap 比创建 Object[] 更快?

c++ - 为什么 boost::equals 要求范围是可复制的?

c# - 类型安全的 Equals()

java - Mockito:如何通过模拟测试我的服务?

java - 在 dynamodb 映射器中使用连字符作为键名

java - 向服务器发送 DELETE 时出现错误 405 方法不允许错误

string - 为什么遍历 HashMap<&str,&str> 会产生 &&str?

java - 具有相同哈希码但不相等的两个实例