2011-03-28 67 views
2

Abstract成为抽象类,A1,A2,...,AnAbstact继承的具体类。 Ai中的每一个都有一个列表Abstract和一个在编译时已知的预定义的基元类型集合,让我们假设我们有一个hush函数,并且每个具体元素的结构中没有“循环”。 e1和e2如何散列复合类?

两个元件是相同的,如果它们具有预定义的原语的相同的值,并且如果在每个E1 Abstract,存在一个在Abstract E2使得e1和e2是相同的。 (换句话说,顺序并不重要)。

我正在寻找一个很好的散列启发式这种问题。它不应该(也就是说,据我所知,不可能)是一个完美的散列函数,但它应该在运行时很好且容易计算。

如果有人能给我一些指导方法来实现这样的功能,或者指导我解决这个问题的文章,我会很高兴。

PS我正在用Java编写,我假设(纠正我,如果我错了)在hash()内置将不足以解决这个问题。
编辑:
列表和原语是建设后固定,但在编译时未知。

+0

订单不重要的列表?这是一套。 – Pops 2011-03-28 14:09:00

+0

@Torgamus:对于性能问题是“重要的” - 我为列表中的每个元素调用一个方法,并且调用顺序可能会提高性能。为了纠正 - 你是对的,这是一套。 – amit 2011-03-28 14:11:33

+0

相关http://stackoverflow.com/questions/3869252/what-is-the-preferred-way-of-implementing-hashcode – andersoj 2011-03-28 14:21:13

回答

1

使用谷歌Guava的公用事业... Objects.hashCode()是伟大的。此外,源代码可用,他们已经解决了您所陈述的问题,因此您可以查看他们的解决方案。

+0

谢谢,我会看看它。他们发表了一篇文章,我可以看看这个吗? – amit 2011-03-28 14:21:15

+1

不知道是否有专门的文章,但项目网站(代码,文档)在这里http://code.google.com/p/guava-libraries/和Guava使用StackOverflow的Q + A,所以你可以找到相当通过使用番石榴标签进行搜索。 – andersoj 2011-03-28 14:22:55

2

如果这些列表在它们被构造后可以改变,那么将哈希函数基于它们将是一个坏主意。想象一下,如果你将你的物体卡入HashMap,然后改变它的一部分。您将无法再在HashMap中找到它,因为它的hashCode会有所不同。

您应该只将hashCode的结果基于不可变的值。如果你的对象中没有任何不可变的值,那么最好的办法就是简单地使用基本的Object.hashCode(),尽管你会在平等测试中失败。

但是,如果这些对象是不可变的,那么我建议为您的元素选择某种排序顺序。然后,您可以计算整个列表中的哈希代码,即使列表的顺序不同,它也会相同,因为您在哈希之前对值进行排序。

+0

这些列表在构建之后是固定的,但在编译时未知。关于您的最后一条语句,如果我对列表进行排序,Object.hashCode()就足够了吗?两个相同的元素(如前所述)会得到相同的散列码吗? – amit 2011-03-28 14:07:39

+0

同意。我已经看到糟糕的代码(使用Apache HashCodeBuilder或其他),每次使用可以更改的字段(在Javabean中不会更改)重新计算哈希值。坏,坏,坏。 – 2011-03-28 14:08:42

+0

否,'Object.hashCode()'将为对象返回不同的值,否则它们看起来是相同的。默认实现返回对象的地址。另外,如果你将循环遍历这样的列表,你可能想要缓存哈希代码,所以你只计算它一次(它听起来像可能是昂贵的)。 – Jonathan 2011-03-28 14:26:38