24

さまざまな列挙型 (さまざまな型) を含むクラスがあります。このクラスは のキーとして使用されますHashMap。クラス hashCode は現在、次のように実装されています。

  public static class Key implements Comparable<Key> {
    final int a;
    final Enum1 enum1;
    final Enum2 enum2;

    @Override
    public int hashCode() {
      return a ^ enum1.hashCode() ^ enum2.hashCode();
    }

    // ... definition of equals and toString ...
  }

enums hashCode が enum の定義で enum 値のインデックスを返すだけの場合、これは最適ではありません (衝突が多すぎます)。のメソッド定義Enum.hashCode()は次のとおりです。

/**
 * Returns a hash code for this enum constant.
 *
 * @return a hash code for this enum constant.
 */
public final int hashCode() {
    return super.hashCode();
}

これが にデリゲートすると仮定するとObject.hashCode()、すべての enum 定数に対して 1 つのインスタンスしか存在せずObject.hashCode()、理論的にはオブジェクトの内部アドレスから派生した整数のようなものになるため、すべて問題ありません。私は正しいですか?

PS: もちろん、同じ列挙型がキーで複数回使用される場合は、より複雑なものを使用する必要があります。

4

4 に答える 4

18

はい、列挙要素のハッシュコードは静的インスタンスから取得され、メモリ位置にバインドされ、一意であるという点で正しいです。

一方、より少ない衝突確率でハッシュコードを生成するより良い方法があります。たとえば、Eclipse が自動生成できるデフォルトを確認してください (右クリックし、[ソース] > [hashCode と equals を生成] を選択します)。

public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((enum1 == null) ? 0 : enum1.hashCode());
    result = prime * result + ((enum2 == null) ? 0 : enum2.hashCode());
    return result;
}

素数をミックスに投入することで (正確な計算は私にはわかりません)、もう少し抵抗力があるはずです。

Eclipse に equals メソッドを生成させることもできることに注意してください。(toStringでも)。それらを盲目的に信頼しなければならないと言っているわけではありませんが、通常は非常に良いスタートです。

于 2012-11-27T09:55:45.547 に答える
4

上で述べたように、列挙型はJavaで不変であるため、列挙型用に生成されたハッシュコードは、文字列が完全なキーであるのと同様に、ハッシュコレクションの完全なキーです。

enum宣言は、特別な種類のクラス宣言です。列挙型には、指定された列挙定数ごとに、パブリックの自己型化されたメンバーがあります。すべての列挙型クラスには、高品質のtoString、hashCode、およびequalsメソッドがあります。すべてがシリアル化可能で、比較可能で、事実上最終的です。クローン可能なものはありません。toStringを除くすべての「オブジェクトメソッド」は最終的なものです。比較とシリアル化を処理し、正しく実行されるようにします。

于 2012-11-27T10:26:31.250 に答える
3

これをOracle 1.6 JVMでテストしました。列挙型は実際に Object.hashCode() に委譲します。そして、それは実行ごとに異なります。したがって、キーは異なる VM / VM インスタンス間で安定していないことに注意してください。したがって、HashMap をシリアル化して別の VM で読み返すと、その VM で構築されたキーを使用して値を検索することはできません。

于 2012-11-27T09:57:41.130 に答える