配列のhashCodeはObjectクラスからの継承

配列のhashCode()メソッドはObjectクラスから継承しているので、異なる配列オブジェクトでは、配列の中身が同一のオブジェクトであったとしてもhashCode()の結果は異なるものになる。
Java仮想マシン仕様の2.15 Arraysに次のように記載されています。

All methods on arrays are inherited from class Object except the clone method, which arrays override.

http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html#16446

フィールドに配列を持つ自作のクラスをHashMapのキーに使おうとして、はまってしまいました*1

配列の内容をもとにハッシュ値を計算するには、ArraysクラスのhashCode()を使うとよいです。equals()も同様。

import java.util.*;

public class Test {

    public static void main(String[] args){
        int[] array1 = new int[]{1,2,3};
        int[] array2 = new int[]{1,2,3};

        System.out.println(array1.equals(array2));
        System.out.println(array1.hashCode());
        System.out.println(array2.hashCode());

        System.out.println();
        
        System.out.println(Arrays.equals(array1, array2));
        System.out.println(Arrays.hashCode(array1));
        System.out.println(Arrays.hashCode(array2));
        
    }
}

結果

false
827574
17510567

true
30817
30817


このメソッド、JDK1.5から導入されてるのだけど、それ以前って配列のハッシュコードを内容から作りたかったら自前で書くしかなかったのか…。不便だ。

*1:配列の内容は変更不可にできないので、キーに格納した後でハッシュ値が変わってしまう恐れを考えたらそもそもキーとして使うべきではないのかもしれない