Java 6では、ツリーセットを作成するときにコンパレータを指定して、セット内のオブジェクトの「自然な順序」をオーバーライドできると理解しています。
Javaがセット内のオブジェクトの「自然なハッシュ」をオーバーライドする「ハッシュ」の提供もサポートしていない理由について何か考えがありますか?
編集:あなたからのインプットを得ることは、将来APIを設計するときに私を助けるかもしれません。
ありがとう。
オブジェクトは、クラス内のメソッドHasher
に対して冗長になります。hashCode()
Object
ハッシュの性質に影響を与えたい場合は、でhashCode()
定義されたメソッドをオーバーライドする必要がありますObject
。equals(Object)
これら2つは常に一緒に実行する必要があるため、必ずオーバーライドしてください。
または他のHashSet
同様のデータ構造は、objectshashCode()
メソッドを使用してハッシュ値を取得し、ビンストレージを決定します。次に、equals()
そのオブジェクトを同じビン内の他のオブジェクトと比較して、同等性を判断します。
生成されるハッシュコードは、その特定のクラスのオブジェクトに固有である必要があります。これは、メソッドをオーバーライドするだけで確実になりhashCode()
、実装ごとに変更する必要はありません。オブジェクトは単に難読化され、追加のHasher
目的を果たしません。異なるデータ構造に格納するために複数のハッシュコードが必要になる単一のユースケースは考えられませんでした。
いくつかの考えられる理由を次に示します。
シンプル- ほとんどの人は複数のハッシュ関数を必要としないため、API をシンプルに保つには、単一の Object.hashCode() アプローチに依存するのが理にかなっています
パフォーマンス- 少なくとも標準ライブラリでは、HashSets や HashMaps などは非常に広く使用されているため、かなり最適化する必要があります。個別の「ハッシャー」を呼び出すオーバーヘッドがあることは意味がありませんが、そのオーバーヘッドが小さくてもかまいません。
プライベート フィールド- hashCode() がプライベート フィールドに依存している可能性があるという問題があり、一部のオブジェクトに対して外部の「ハッシュ」を作成するのが難しい場合があります。
します!Object.hashCodeメソッドを確認してください。
あなたの質問をもう一度読んだ後、私は銃を飛び越えたかもしれません。私は今あなたが自然なhshingを「オーバーライドする」と言ったのを見ます。通常、オブジェクトレベルでハッシュ値をオーバーライドし、オーバーライドするHasherの使用を省略します。
ハッシュは、コンパレータよりも普遍的であることが意図されています。つまり、ハッシュはほとんどの場合、衝突の可能性がほとんどない均一な信頼できない値を作成する必要があります。それらが使用されるコンテナは、特別なハッシャーを必要とすることはめったにありません。
オブジェクトのハッシュコードを変更するには、ハッシュコードを追加するオブジェクトをラップします。オブジェクトを多数の方法でソートしたいが、複数のハッシュ戦略を持たせたくない場合があることを前提としています。
cf Trove4jは、HashMapのハッシュ戦略をサポートしています。このライブラリを使用している間、私は覚えていると、カスタムハッシュ戦略を使用したことがあります。