2011-03-28 63 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