JavaでのhashCodeの使用は何ですか?


161

Javaでは、obj.hashCode()いくつかの値を返します。プログラミングにおけるこのハッシュコードの使用は何ですか?


この質問は、いくつかの詳細を追加します。 stackoverflow.com/questions/18078779/...
MaheshVarma

1
この投稿で与えられた素晴らしい説明。eclipsesource.com/blogs/2012/09/04/...
ビジェイVankhede

回答:


222

hashCode()するために使用されるバケットHashのような実装HashMapHashTableHashSet

から受け取った値は、セット/マップの要素を格納するためhashCode()バケット番号として使用されます。このバケット番号は、セット/マップ内の要素のアドレスです。

実行contains()すると、要素のハッシュコードが取得され、ハッシュコードが指すバケットを探します。同じバケット内に複数の要素が見つかった場合(複数のオブジェクトが同じハッシュコードを持つことができます)、equals()メソッドを使用してオブジェクトが等しいかどうかを評価し、次にcontains()trueかfalseかを判断します。セットに追加されたかどうか。


28
こんにちはバディ..非常に良い答えですが、理解しやすい実用的な例と同じように非常に興味深いリンクを見つけました:coderanch.com/t/321515/java/java/HashCode
Logicalj

アイシュありがとうございます。今、私はバケット関連の説明でハッシュコードについて明確な知識を得ました。
Balasubramani、2015年

2
「同じバケット内に複数の要素が見つかった場合は、equals()を使用して評価します」。したがって、一致するハッシュコード要素が1つしか見つからなかった場合、直接trueを返しますか?しかし、複数のオブジェクトが同じハッシュコードを持つ可能性があるためequals()、一致した要素が等しいかどうかを評価するために実行する必要があるため、予期しない結果になる可能性があります。
Saorikido 2017年

バケットはさておき、ハッシュコードはオブジェクトがメモリに各オブジェクトを格納する順序を決定するために呼び出すメソッドです。オブジェクトが等しい場合、それらのハッシュコードも等しくなければなりません。(このステートメントの逆は偽です)
NoName

1
プログラマーがhashCode()メソッドを手動で呼び出すのはどのような場合ですか?
枢機卿-モニカを

33

Javadocから:

オブジェクトのハッシュコード値を返します。このメソッドは、によって提供されるようなハッシュテーブルのメリットのためにサポートされていjava.util.Hashtableます。

の一般契約hashCodeは次のとおりです。

  • Javaアプリケーションの実行中に同じオブジェクトで2回以上呼び出される場合、オブジェクトの等値比較で使用される情報が変更されていhashCodeなければ、メソッドは常に同じ整数を返す必要があります。この整数は、アプリケーションのある実行から同じアプリケーションの別の実行まで一貫性を保つ必要はありません。

  • equals(Object)メソッドに従って2つのオブジェクトが等しい場合、2つのオブジェクトのhashCodeそれぞれでメソッドを呼び出すと、同じ整数の結果が生成される必要があります。

  • されていない 2つのオブジェクトに応じて等しくない場合に必要なequals(java.lang.Object)メソッドは、呼び出しhashCode異なる整数結果を生成しなければならない二つの物体のそれぞれに方法を。ただし、プログラマは、異なるオブジェクトに対して異なる整数の結果を生成すると、ハッシュテーブルのパフォーマンスが向上する可能性があることに注意する必要があります。

合理的に実用的である限り、クラスObjectによって定義されたhashCodeメソッドは、個別のオブジェクトに対して個別の整数を返します。(これは通常、オブジェクトの内部アドレスを整数変換することによって実装されますが、この実装手法はJavaプログラミング言語では必要ありません。)


14

によって返される値hashCode()は、オブジェクトのハッシュコードです。これは、16進数のオブジェクトのメモリアドレスです。

定義により、2つのオブジェクトが等しい場合、それらのハッシュコードも等しくなければなりません。equals()メソッドをオーバーライドすると、2つのオブジェクトが同等と見なされ、Objectの実装が無効になる方法が変更されhashCode()ます。したがって、equals()メソッドをオーバーライドする場合は、hashCode()メソッドもオーバーライドする必要があります。

この回答は、Java SE 8公式チュートリアルドキュメントからのものです。


13

hashCode()オブジェクトを受け取り、数値を出力する関数です。オブジェクトが変更されない場合、オブジェクトのハッシュコードは常に同じです。

以下のような関数HashMapHashTableHashSetストアオブジェクトへのニーズが使用するなど、hashCodeその内部配列のサイズは、オブジェクトを格納するためにどのような「メモリ位置」(すなわち、配列の位置)に選択する剰余を。

衝突が発生する場合があり(2つのオブジェクトが最終的に同じハッシュコードになる)、もちろん、慎重に解決する必要があります。


6

ハッシュコードはあなたのビジネスロジックとは何の関係もありませんが、ほとんどの場合それを処理する必要があります。オブジェクトがハッシュベースのコンテナー(HashSet、HashMap ...)に配置されると、コンテナーは要素のハッシュコードを配置または取得するためです。


いいえ、ありません。キーを置く/取得します。hashCodeはバケット化にのみ使用されます
Marquis of Lorne

3

ハッシュコードは、任意のオブジェクトから生成された番号です。

これにより、オブジェクトをハッシュテーブルにすばやく格納/取得できます。

次の簡単な例を想像してみてください。

目の前のテーブルの上。それぞれに1から9までの番号が付いた9つのボックスがあります。これらのボックスに格納する非常に異なるオブジェクトの山もありますが、いったんそこに入ると、できるだけ早くそれらを見つけることができる必要があります。

必要なのは、各オブジェクトを配置したボックスを即座に決定する方法です。これは、インデックスのように機能します。キャベツを見つけることに決めたので、キャベツが入っている箱を調べ、その箱に直行してそれを手に入れます。

インデックスに煩わされたくない場合は、オブジェクトが存在するボックスをオブジェクトからすぐに見つけられるようにしたいとします。

例では、これを行う非常に簡単な方法を使用しましょう-オブジェクトの名前の文字数。したがって、キャベツはボックス7、エンドウ豆はボックス3、ロケットはボックス6、バンジョーはボックス5のようになります。

サイはどうですか?10文字なので、アルゴリズムを少し変更して「折り返し」し、10文字のオブジェクトをボックス1に入れ、11文字をボックス2に入れるというようにします。それはあらゆるオブジェクトをカバーするはずです。

箱には複数のオブジェクトが含まれる場合がありますが、ロケットを探している場合は、キャベツ、エンドウ豆、バンジョー、サイの山全体を確認するよりも、ピーナッツとロケットを比較する方がはるかに高速です。

それはハッシュコードです。オブジェクトから数値を取得してHashtableに格納できるようにする方法。Javaでは、ハッシュコードは任意の整数にすることができ、各オブジェクトタイプは独自のコードを生成します。Objectの「hashCode」メソッドを検索します。

ソース- ここに


-1

hashCode()の用途の1つは、キャッチメカニズムの構築です。この例を見てください:

        class Point
    {
      public int x, y;

      public Point(int x, int y)
      {
        this.x = x;
        this.y = y;
      }

      @Override
      public boolean equals(Object o)
      {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Point point = (Point) o;

        if (x != point.x) return false;
        return y == point.y;
      }

      @Override
      public int hashCode()
      {
        int result = x;
        result = 31 * result + y;
        return result;
      }

class Line
{
  public Point start, end;

  public Line(Point start, Point end)
  {
    this.start = start;
    this.end = end;
  }

  @Override
  public boolean equals(Object o)
  {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    Line line = (Line) o;

    if (!start.equals(line.start)) return false;
    return end.equals(line.end);
  }

  @Override
  public int hashCode()
  {
    int result = start.hashCode();
    result = 31 * result + end.hashCode();
    return result;
  }
}
class LineToPointAdapter implements Iterable<Point>
{
  private static int count = 0;
  private static Map<Integer, List<Point>> cache = new HashMap<>();
  private int hash;

  public LineToPointAdapter(Line line)
  {
    hash = line.hashCode();
    if (cache.get(hash) != null) return; // we already have it

    System.out.println(
      String.format("%d: Generating points for line [%d,%d]-[%d,%d] (no caching)",
        ++count, line.start.x, line.start.y, line.end.x, line.end.y));
}

「キャッチメカニズムの構築」とはどういう意味ですか?そして、このコードはそれをどのように説明しますか?
ローンの侯爵

-1

hashCode()あるユニークなすべてのオブジェクトを作成するためのJVMによって生成されるコードは。

hashCode()Hashtable、Hashmapなどのハッシュ関連のアルゴリズムで何らかの操作を実行するために使用します。

hashCode()一意のコードを持つオブジェクトを検索するときに、そのオブジェクトを見つけるのに役立つため、検索操作が簡単になるという利点があります。

しかしhashCode()、オブジェクトのアドレスであるとは言えません。これは、JVMがオブジェクトごとに生成する一意のコードです。

そのため、現在、ハッシュアルゴリズムが最も人気のある検索アルゴリズムです。


4
ハッシュコードは一意ではありません。2つの等しくないオブジェクトが同じハッシュコードを返す場合があります。
Ranielle Canlas
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.