1.2. java.lang.ObjectのequalsメソッドとhashCodeメソッド
「Hashtable」の説明の前に、オブジェクトの同一性について説明します。
JavaでオブジェクトAとオブジェクトBが「等しい」という場合、2つの意味が考えられます。1つはAとBが同じオブジェクトである事。もう1つはAとBが同じ内容のデータをもつオブジェクトであると言う事です。前者の意味での同一性の判定方法が「==」で、後者の意味での同一性の判定方法が「equals」メソッドを用いた手法です。「String」クラスのオブジェクトで説明します。
String a = new String("test"); String b = new String("test");
上記の「String」オブジェクト「a」と「b」は意味的には同じです。しかし別々のインスタンスですので、オブジェクト的には異なります。
System.out.println(a == b); System.out.println(a.equals(b));
したがって上の出力は「false」を、下の出力は「true」を返します。ただしラッパークラスを除けば、ほとんどのクラスで「equals」メソッドは、同じオブジェクトを指し示している場合のみ「true」を返すので、「==」と「equals」メソッドの結果は同じになります。「equals」メソッドをオーバーライドした場合に、結果が異なる可能性があります。したがって通常はどちらを使用しても問題ありません。しかし「String」のように「==」は人間の直感とずれる場合が多いので、「equals」メソッドを使用するほうが無難でしょう。
次の節で説明するHashtableクラスでは、この「equals」メソッドと「hashCode」メソッドを用いてオブジェクトの同一性を判定します。「hashCode」メソッドはオブジェクトのハッシュ値を返すメソッドで、コレクションクラス内部のデータ管理でよく用いられます。「hashCode」メソッドが返すハッシュ値は以下のような性質を持つものです。
- アプリケーションの実行中において、同じオブジェクトが返すハッシュ値は変化してはならない。ただしオブジェクト内部の情報が変化し、equalsメソッドによる比較結果が変化する場合には、その限りでない。またアプリケーションが再起動された場合にも、ハッシュ値が変化しても構わない。
- equalsメソッドによって同じとみなされる複数のオブジェクトは、同じハッシュ値を返さなければならない。
- equalsメソッドによって異なるとみなされる複数のオブジェクトが、異なるハッシュ値を返さなくても構わない。ただし異なるハッシュ値を返した方が、コレクションクラスにおけるパフォーマンスの向上が期待できる。
したがってequalsメソッドをオーバーライドした場合には、equalsメソッドがtrueを返す場合には同じハッシュ値を返すように、hashCodeメソッドもオーバーライドしなければなりません。
(実習課題3)
以下のオブジェクトの同一性を、「==」と「equals」メソッドで比較した場合の結果の違いを確かめなさい。またこれらのハッシュ値を確かめなさい。
String a = "test"; String b = new String("test"); String c = "te" + "st"; String d = "te" + new String("st"); String e = new String("te") + new String("st")