2012-03-22 139 views
2

在什么情况下给出了hashCode和equals()的正确实现,下面的代码可以返回false吗?java hashtable包含奇怪

myLinkedHashMap.containsKey(myLinkedHashMap.keySet().iterator().next()) 
+0

“确定性”是否指“正确”? – 2012-03-22 21:29:00

+0

它在这种情况下并不重要,因为它是同一个对象,对吧?所以只要对同一个对象的2次调用产生相同的hashCode,就应该返回true。但是,是的,这也是正确的。 – 2012-03-22 21:30:01

+1

但“确定性”并不意味着“对同一对象的2个调用产生相同的hashCode”。关于'ArrayList .hashCode'没有任何*非确定性的*,但看到我的答案... – 2012-03-22 21:34:44

回答

7

我可以想到的最可能的情况是即使hashCode是“确定性”,它可能基于可变字段。如果您在Map中更改用于计算hashCode的字段,那么您将无法再找到它。

编辑:应澄清你'通常'将无法找到它了。偶尔它仍然可以工作,因为两个数字仍然可以重新进入同一个桶。当然,这只会增加混乱发生!

+0

是的,突变。谢谢。 – 2012-03-22 21:40:20

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>哈希码是确定的,但是,这并不意味着它不会改变,如果列表中的内容发生变化。

1

如果您的hashCodeequals彼此不同意,则可能返回错误。例如,如果equals方法总是返回false,则这将返回false,因为没有任何对象与映射中的键相等。

希望这会有所帮助!

2
  1. 如果hashCode()是基于是可变和这些属性在插入后改变实例属性,迭代过程中hashCode()调用将返回不同的东西。 equals()应该基于这些相同的属性,它也会失败。

  2. 当另一个线程已经删除了所有下一个在迭代中间的Map项目,将有没有更多的next()

我不会使用hashCode()值作为键,我会把你自己的对象。

+0

没有线程。 – 2012-03-22 21:31:22

+1

并不重要,如果你正在考虑的特定实例不使用一个线程,你的**问题**问什么时候会发生,这是可能发生的一种情况。 – 2012-03-22 21:35:13

0

您可能需要先检查hasNext()。

+0

不,它在那里。绝对有元素。 – 2012-03-22 21:32:13

3

我看到的每个散列算法都是“确定性”的,因为对于给定的一组输入值,您可以得到相同的散列值。

如果根据对象的可变属性计算哈希代码,则哈希代码在哈希映射后会发生变化,如果这些可变属性中的任何一个发生更改。

0

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