2010-12-14 23 views
2

在Java 6中,我的理解是,創建它時可以爲TreeSet提供一個Comparator,以覆蓋集合中對象的「自然排序」。爲什麼我們可以提供一個比較器給TreeSet,但不能像Hasher那樣提供給HashSet?

你有什麼想法,爲什麼Java不支持提供一個「Hasher」來覆蓋集合中對象的「自然散列」?

編輯: 從您那裏獲得輸入可能會幫助我在將來設計API時。

謝謝。

+1

的API是它是什麼。問「爲什麼」只能是猜測。 – skaffman 2010-12-14 14:53:51

+1

你可以爲Set和equals提出同樣的問題。 – Ralph 2010-12-14 15:00:18

+0

+1 @Ralph,機智! – Russell 2010-12-14 15:07:23

回答

2

這裏有幾個可能的原因:

  • 簡單 - 大多數人並不需要多個散列函數,所以要保持API的簡單,它是有道理的依靠單一的對象。的hashCode()方法

  • 性能 - 在標準庫中至少 HashSets和包含HashMap等需 相當高度優化的,因爲它們是如此 廣泛使用。 沒有意義的調用 單獨的「hasher」,然而開銷可能很小。

  • 私人領域 - 那裏是 hashCode()方法可以依靠私人 領域的問題,它可能難以 創造一些 對象外部「hashers」。

1

它的確如此!檢查出Object.hashCode方法。

再次閱讀您的問題後,我可能會跳過槍。我現在看到你說「重寫」了自然的噓聲。通常我們會覆蓋對象級別的散列值,並放棄使用覆蓋的哈希值。

哈希值是比較普遍的比較器。也就是說,哈希值幾乎總是會產生一致的不可信值,並且幾乎沒有碰撞的可能性。他們使用的容器應該很少需要專門的散列器。

+0

你回來回答這個問題! +1 :) – Russell 2010-12-14 15:05:30

2

A Hasher對象對於Object類中的hashCode()方法是多餘的。

如果你想影響散列的性質,你應該覆蓋Object定義的hashCode()方法。只要一定要覆蓋equals(Object),因爲這兩個應該總是一起。

A HashSet或其他類似的數據結構將使用對象hashCode()方法來獲得散列值以確定箱的存儲。然後它將使用equals()將該對象與同一箱中的其他對象進行比較以確定相等性。

生成的哈希碼對於該特定類型的對象必須是唯一的。這可以簡單地通過覆蓋方法來保證,並且不需要從實現改變到實現。一個對象只會混淆,不會爲其他目的服務。我想不出一個用例需要多個散列碼來存儲不同的數據結構。

+0

絕對正確,你爲什麼有一個比較器而不是哈希的輸入是? – Russell 2010-12-14 15:15:46

+0

當'Object'上有'hashCode()'方法時,你不需要'Hasher'。如果'Object'有一個'compareTo()'方法,那麼你就不需要'Comparator'。 – 2010-12-14 15:56:12

+0

如果你想重寫自然排序,你需要一個比較器,但是我知道你來自哪裏。謝謝! – Russell 2010-12-14 17:18:14

0

您可以通過包裝在一個對象中來改變對象的哈希代碼,該對象以您的方式填充哈希代碼。這個假設是你可能想讓一個對象按數字排序,但是不能有多個散列策略。

c.f. Trove4j支持HashMap的散列策略,而當我使用這個庫時,我經常只使用自定義散列策略。

相關問題