Java 如何散列复合类?

Java 如何散列复合类?,java,hash,heuristics,Java,Hash,Heuristics,让Abstract成为一个抽象类,A1,A2,…,一个继承自absact的具体类。Ai中的每一个都有一个Abstract列表和一组预定义的、在编译时已知的基元类型,假设我们为它们提供了一个静默函数,并且每个具体元素的结构中没有“循环” 如果两个元素e1和e2具有相同的预定义原语值,则它们是相同的;如果对于e1中的每个抽象,e2中存在一个抽象,则e1和e2是相同的。(换句话说,秩序并不重要) 我正在为这类问题寻找一个好的哈希启发式算法。它不应该(据我所知,不可能)是一个完美的哈希函数,但它应该是好

Abstract
成为一个抽象类,
A1,A2,…,一个继承自
absact
的具体类。
Ai
中的每一个都有一个
Abstract
列表和一组预定义的、在编译时已知的基元类型,假设我们为它们提供了一个静默函数,并且每个具体元素的结构中没有“循环”

如果两个元素e1和e2具有相同的预定义原语值,则它们是相同的;如果对于e1中的每个
抽象
,e2中存在一个
抽象
,则e1和e2是相同的。(换句话说,秩序并不重要)

我正在为这类问题寻找一个好的哈希启发式算法。它不应该(据我所知,不可能)是一个完美的哈希函数,但它应该是好的,并且在运行时易于计算

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

PS我是用Java写的,我假设(如果我错了请纠正我)内置的
hash()
对于这个问题来说不够好。
编辑:

列表和原语在构造之后是固定的,但在编译时是未知的。

如果这些列表在构造之后可以更改,那么将哈希函数建立在它们之上是一个坏主意。想象一下,如果您将对象插入一个
HashMap
,然后更改了其中的一部分。您将无法再在
HashMap
中找到它,因为它的
hashCode
将不同

您应该仅基于不可变的值来计算
hashCode
的结果。如果您的对象中没有任何不可变的值,那么最好的选择可能是简单地使用基本的
对象。hashCode()
,尽管您会在平等性测试中失败


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

使用Google Guava的实用程序。。。太好了。另外,源代码是可用的,它们已经解决了您所说的问题,因此您可以查看它们的解决方案。

列表在构造后是固定的,但在编译时是未知的。关于您的上一条语句,如果我对列表进行排序,Object.hashCode()就足够了吗?两个相同的(如前所述)元素是否会得到相同的哈希代码?同意。我见过一些糟糕的代码(使用ApacheHashCodeBuilder或其他东西),每次使用可以更改的字段(在Javabean中)重新计算哈希。坏的,坏的,坏的。不,
Object.hashCode()
将为对象返回不同的值,否则这些值将看起来相同。默认实现返回对象的地址。此外,如果您要在这样的列表中循环,您可能希望缓存哈希代码,以便只计算一次(听起来可能很昂贵)。顺序不重要的列表?这是一个集合。@Torgamus:这对于性能问题是“重要的”——我正在为列表中的每个元素调用一个方法,调用的顺序可能会提高性能。请更正-你是对的,这是一套。谢谢,我来看看。他们发表了一篇我可以看一看的文章吗?不知道是否有专门的文章,但是项目站点(代码,文档)在这里,Guava使用StackOverflow表示Q+a,所以你可以通过使用Guava标记进行搜索来找到很多内容。