🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

2回答

1582閲覧

配列のhashコードが同値を入れた変数なのにhashコードが異なるのはなぜですか?

sobue

総合スコア329

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2019/09/07 00:43

java

1 String[] arrayStr1 = { "hoge", "fuga" }; 2 String[] arrayStr2 = { "hoge", "fuga" }; 3 4 System.out.println(arrayStr1.toString()); 5 System.out.println(arrayStr2.toString()); 6 7 List<String> strList1 = new ArrayList<String>(); 8 strList1.add("hoge"); 9 strList1.add("fuga"); 10 List<String> strList2 = new ArrayList<String>(); 11 strList2.add("hoge"); 12 strList2.add("fuga"); 13 14 System.out.println(Integer.toHexString(strList1.hashCode())); 15 System.out.println(Integer.toHexString(strList2.hashCode()));

結果
arrayStr1:[Ljava.lang.String;@15db9742
arrayStr2:[Ljava.lang.String;@6d06d69c
strList1:61db625
strList2:61db625

リストは同じですが、配列のhashコードが異なります。
なぜ異なるのでしょうか?
また、変数名を変えてもhashコードが変わりませんでした。
hashコードの生成のルールについてもご教示いただきたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

なぜ異なるのでしょうか?

Javaの場合、配列はインスタンスの一致しか見ないので、中身が同じでもequals一致しませんJPCERT/CC)。ということで、「equalsで一致しないものはhashCodeも別のものにすべき」というルールに従って、hashCodeも別なものが割り振られます。

また、変数名を変えてもhashコードが変わりませんでした。

hashCodeインスタンスに結びついたものなので、どの変数に入れようが同じインスタンスであれば同じ値です。

hashコードの生成のルールについてもご教示いただきたいです。

hashCodeを使う側としては、具体的なルールはむしろ考えてはいけません(何らかの事情で、生成されるhashCodeの具体的な値が変化することも考えられます)。hashCodeの一般契約(Oracle)が成立していれば動くようにプログラムを書くべきで、使う側がそれ以上の詳細に立ち入るのは不適切です。

  • equalsで比較して等しくなるオブジェクトは、同じhashCodeを返す
  • equalsでの比較状況が変化しない場合、hashCodeも変化しない
  • equalsで比較して等しくならない場合、違うhashCodeを返すようにしたほうが効率化する

投稿2019/09/07 01:36

maisumakun

総合スコア145971

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sobue

2019/09/07 04:35 編集

配列はインスタンスが同じであれば、同じとのことですが、リスト型の場合、インスタンスが異なってもhashコードが同じです。配列のみの特別仕様ということでしょうか?
maisumakun

2019/09/07 04:48

Listは中身まで見てequalsの同値判定を行いますので、それに合わせて「中身が同じなら同じになる」ようなhashCodeを生成しています。 ルートクラスのObject.hashCodeはインスタンスごとの生成ですので、特別な実装なのはListのほうです。
guest

0

ベストアンサー

Listなど、大抵のクラスはObjectクラスのメソッドをオーバーライドしていますが、配列はそのオーバーライドはしていません。
Listは、「比較の相手もListで、その中身が順序含めて一致する」時のみ「等しい」(=equalsでtrue)と判定したいために、それに沿うようにequalsをオーバーライドし、また規約に従うためにhashCodeも中身を含めて計算しています。
一方、配列は先述の通りObjectクラスのメソッドをオーバーライドしません。equalsは「同一のオブジェクトの場合のみtrue」だけなので、中身がどうとかは関係ありません。ですから当然hashCodeの計算も中身は関係ありません。

投稿2019/09/07 05:55

swordone

総合スコア20669

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問