LinkedHashMap如何找不到由迭代器生成的条目?

问题描述 投票:2回答:7

在什么情况下,只要正确实现hashCode和equals(),以下代码就可以返回false?

myLinkedHashMap.containsKey(myLinkedHashMap.keySet().iterator().next())
java equals hashcode
7个回答
7
投票

尽管hashCode是“确定性的”,但我可能想到的最有可能的情况可能是基于可变字段。如果在将hashCode放入Map后更改用于计算的字段,则将无法再找到它。

编辑:通常应澄清您的情况,将不再能找到它。有时它仍然可以使用,因为两个数字仍可以重新哈希到同一个存储桶中。当然,这只会在发生时加剧混乱!


3
投票

我见过的每个哈希算法都是“确定性的”,因为对于给定的一组输入值,您将获得相同的哈希值。

如果哈希码是基于对象的可变属性计算的,则如果这些可变属性中的任何可变属性被更改,则哈希代码将在其位于哈希图中之后更改。


2
投票

不清楚“确定性”是什么意思,但是在将密钥插入哈希映射后,对密钥进行任何更改哈希的更改都可以轻松地产生这种效果。

import java.util.*;

public class Test {
  public static void main(String[] args) {
    List<String> strings = new ArrayList<String>();
    Map<List<String>, String> map = new LinkedHashMap<List<String>, String>();

    map.put(strings, "");
    System.out.println(map.containsKey(map.keySet().iterator().next())); // true
    strings.add("Foo");
    System.out.println(map.containsKey(map.keySet().iterator().next())); // false
  }
}

ArrayList<T>的哈希码是确定性的,但这并不意味着如果列表的内容更改,它也不会更改。


2
投票
  1. 如果hashCode()基于mutable的实例属性,并且在插入后更改了这些属性,则迭代期间的hashCode()调用将返回不同的内容。并且equals()应该基于这些相同的属性,并且也会失败。

  2. 当另一个线程在迭代过程中从Map中删除所有next项时,将不再有next()

我不会将hashCode()值用作键,我会把对象本身作为对象。


1
投票

如果您的hashCodeequals彼此不同意,则可能返回false。例如,如果equals方法始终返回false,则将返回false,因为没有任何对象可以与映射中的键进行比较。

希望这会有所帮助!


0
投票

您可能想先检查hasNext()。


0
投票

您可以在获取第一个键和调用containsKey之间的另一个线程中删除第一个键。

© www.soinside.com 2019 - 2024. All rights reserved.