java哈希对象

时间:2012-01-28 13:35:57

标签: java hash reference cycle

我希望能够确定我之前是否遇到过一个对象 - 我有一个图形实现,我想看看我是否已经创建了一个循环,可能是通过使用乌龟迭代Node对象/野兔弗洛伊德算法。

但我希望每次都避免通过我的“看到”节点列表进行线性搜索。如果我只有键的哈希表,这将是很好的。我可以以某种方式哈希一个对象吗?难道java对象只是引用内存中的位置吗?我想知道如果碰撞会有多少问题......

4 个答案:

答案 0 :(得分:5)

简单的答案是创建一个HashSet并在第一次遇到它时将每个节点添加到集合中。

唯一不起作用的情况是,如果您为节点类重载hashCode()equals(Object)以基于节点内容(或其他)实现相等性。然后你需要:

  • 使用IdentityHashMap类使用==System.identityHashcode而不是equals(Object)hashCode(),或
  • 使用您自己的对象标识来自己构建一个哈希表。

  

java对象是不是只引用了内存中的位置?

是和否。是的,引用由内存地址表示(在大多数JVM上)。问题是1)你无法掌握地址,2)当GC重新定位对象时它可以改变。这意味着您不能将对象地址用作哈希码。

identityHashCode方法通过根据内存地址返回最初的值来解决此问题。如果您再次为同一个对象调用identityHashCode,则可以保证获得与之前相同的值...即使该对象已被重新定位。

  

我想知道如果碰撞会出现多少问题......

identityHashCode方法生成的哈希值可能会发生冲突。 (也就是说,两个不同的对象可以具有相同的标识哈希码值。)任何使用这些值的东西都必须处理这个问题。 (标准HashSetIdentityHashMap类负责处理这些冲突......如果您选择使用它们。)

答案 1 :(得分:4)

  

我希望能够确定我是否遇到了一个物体   前

使用IdentityHashMap。这是您工作的理想选择,因为它不是equals,而是==实施。

答案 2 :(得分:2)

看看HashSet。请注意,为了使对象能够与HashSet一起使用,他们需要提供hashCode类的equalsjava.lang.Object方法的正确实现。

答案 3 :(得分:1)

您需要为对象实现哈希函数。这是通过覆盖hashCode()中定义的java.lang.Object来完成的。 HashMapHashSet等使用此方法来存储对象。在hashCode()中,由您来计算对象的哈希值。不要忘记同时实施equals() - 方法!

查看Java集合框架(http://docs.oracle.com/javase/tutorial/collections/)