我正在尝试检查两个节点是否相同,这意味着它们具有相同数量的子节点,并且这些子节点会导致完全相同的状态。因此,我有效地尝试比较两个节点处的子树。我想知道是否可以使用散列来进行这种相等性检查。
不,不应该使用散列来检查相等性。这不是它的目的。它最终可以帮助您找出对象是否不相等,但它不会告诉您它们是否相等。
相同的对象会产生相同的哈希值,但是两个不相等的不同对象也可以产生相同的哈希值。换句话说,如果散列值不同,你肯定知道对象是不同的。而已。
如果要测试相等性,则需要实现 equals。在您的情况下,您的方法可能会递归并引发堆栈溢出。如果您的对象包含对自身的引用怎么办?
如果要生成哈希,可以考虑数组的大小(以及它是否为空的事实),但我不会尝试使用数组中对象的哈希值,因为可能无限循环。它并不完美,但已经足够好了。
还有另一种激进的方法也可以提供良好的结果。不是动态计算哈希值,而是为每个 Node 对象实例设置一个随机的 int 值(我的意思是在创建时一劳永逸并始终返回该值)。在您的情况下,您不会通过获取数组中对象实例的哈希值来冒无限循环的风险。
如果哈希值相等,那么您需要开始比较数组对象实例。
REM:如果节点包含其他属性,则计算这些其他属性的哈希并忘记数组。当且仅当两个对象之间的哈希值相同时,才开始调查数组内容/大小。
REM2:评论提到 DAG 图,这意味着我们不会遇到递归问题。但是,该条件不足以保证 deepHashCode() 会成功。此外,这也将是矫枉过正。有一种更有效的方法可以解决这个问题。
如果 Node 使用的 hash 方法只使用数组来计算 hash 值,那么 deepHashCode() 可能会起作用。但这不会是有效的。如果哈希方法使用其他节点属性,那么这些属性也必须相等。
有一种更快的方法来比较节点是否相等。用唯一的编号标记每个节点实例。然后,要比较两个节点,首先比较它们的数组大小。如果相等,则使用它们的唯一编号比较每个数组中的节点。如果一个数组没有“拥有”另一个节点,那么我们不是在处理相等的节点。这个解决方案比递归要快得多。