[英]java hashing objects
I'd like to be able to determine whether I've encountered an object before - I have a graph implementation and I want to see if I've created a cycle, probably by iterating through the Node objects with a tortoise/hare floyd algorithm. 我希望能够确定之前是否遇到过对象-我有一个图形实现,并且想查看是否创建了一个循环,可能是通过使用乌龟/野兔floyd算法遍历Node对象。
But I want to avoid a linear search through my list of "seen" nodes each time. 但是我想避免每次都在我的“可见”节点列表中进行线性搜索。 This would be great if I had a hash table for just keys. 如果我只有键的哈希表,那就太好了。 Can I somehow hash an object? 我可以以某种方式哈希对象吗? Aren't java objects just references to places in memory anyway? Java对象不是只引用内存中的位置吗? I wonder how much of a problem collisions would be if so.. 我想知道如果发生冲突,会有多少问题。
The simple answer is to create a HashSet
and add each node to the set the first time you encounter it. 简单的答案是创建一个HashSet
并在第一次遇到它时将每个节点添加到该集合中。
The only case that this won't work is if you've overloaded hashCode()
and equals(Object)
for the node class to implement equality based on node contents (or whatever). 唯一不起作用的情况是,如果您为节点类重载了hashCode()
和equals(Object)
以实现基于节点内容(或其他内容)的相等性。 Then you'll need to: 然后,您需要:
IdentityHashMap
class which uses ==
and System.identityHashcode
rather than equals(Object)
and hashCode()
, or 使用IdentityHashMap
类,该类使用==
和System.identityHashcode
而不是equals(Object)
和hashCode()
,或者 Aren't java objects just references to places in memory anyway? Java对象不是只引用内存中的位置吗?
Yes and no. 是的,没有。 Yes, the reference is represented by a memory address (on most JVMs). 是的,引用由内存地址表示(在大多数JVM上)。 The problem is that 1) you can't get hold of the address, and 2) it can change when the GC relocates the object. 问题在于1)您无法获得该地址,并且2)当GC重新定位该对象时,它可以更改。 This means that you can't use the object address as a hashcode. 这意味着您不能将对象地址用作哈希码。
The identityHashCode
method deals this by returning a value that is initially based on the memory address. identityHashCode
方法通过返回最初基于内存地址的值来解决此问题。 If you then call identityHashCode
again for the same object, you are guaranteed to get the same value as before ... even if the object has been relocated. 如果随后再为同一对象调用identityHashCode
,则即使对象已重定位,也可以确保获得与以前相同的值。
I wonder how much of a problem collisions would be if so.. 我想知道如果发生冲突,会有多少问题。
The hash values produced by the identityHashCode
method can collide. identityHashCode
方法产生的哈希值可能会发生冲突。 (That is, two distinct objects can have the same identity hashcode value.) Anything that uses these values has to deal with this. (也就是说,两个不同的对象可以具有相同的标识哈希码值。)使用这些值的任何事物都必须对此进行处理。 (The standard HashSet
and IdentityHashMap
classes take care of these collisions ... if you chose to use them.) (标准的HashSet
和IdentityHashMap
类可以解决这些冲突……如果您选择使用它们。)
I'd like to be able to determine whether I've encountered an object before 我希望能够确定之前是否遇到过物体
Use an IdentityHashMap . 使用IdentityHashMap 。 It is the ideal for your job since it is not an equals
but a ==
implementation. 这是您的工作的理想选择,因为它不是equals
而是==
实现。
You'll need to implement a hash function for your objects. 您需要为您的对象实现一个哈希函数。 This is done by overriding hashCode()
defined in java.lang.Object
. 这是通过覆盖java.lang.Object
定义的hashCode()
来完成的。 This method is used by HashMap
, HashSet
etc to store objects. HashMap
, HashSet
等用于存储对象。 In hashCode()
it's up to you to calculate a hash for the object. 在hashCode()
,由您来计算对象的哈希值。 Don't forget to also implement the equals()
-method! 别忘了还要实现equals()
-方法!
Take a look at Java collection framework (http://docs.oracle.com/javase/tutorial/collections/) 看一下Java收集框架(http://docs.oracle.com/javase/tutorial/collections/)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.