paint-brush
キーの変更、値の喪失@mcsee
544 測定値
544 測定値

キーの変更、値の喪失

Maximiliano Contieri4m2025/02/24
Read on Terminal Reader

長すぎる; 読むには

ハッシュコレクションのキーとして可変オブジェクトを使用する場合、それらを変更すると契約が破棄されます。
featured image - キーの変更、値の喪失
Maximiliano Contieri HackerNoon profile picture
0-item


キーの変更、値の喪失


TL;DR: ハッシュ コレクションのキーとして可変オブジェクトを使用する場合、それらを変更すると契約が破棄されます。

問題😔

  • 失われた価値観
  • ハードデバッグ
  • 最小の驚きの原則違反
  • 予期しない動作

解決策 😃

  1. 不変オブジェクトをキーとして使用します。
  2. equals/hashCodeを適切にオーバーライドします。
  3. 最終フィールドを使用する(言語で許可されている場合)
  4. 変異後の再ハッシュ(これは過剰なエンジニアリングの解決策です)

コンテキスト 💬

ハッシュ コレクションのキーとして可変オブジェクトを使用する場合、関連オブジェクトを追加した後にキーを変更すると、オブジェクトを取得できなくなる可能性があります。


これは、ハッシュ コードが変更され、コレクションが正しいバケット内でオブジェクトを見つけることができないために発生します。

サンプルコード 📖

間違いです❌

 class MutableKey { int id; MutableKey(int newId) { this.id = newId; } @Override public int hashCode() { return this.id; } @Override public boolean equals(Object objectToCompare) { if (this == objectToCompare) return true; MutableKey that = (MutableKey) objectToCompare; return id == that.id; } } MutableKey key = new MutableKey(42); Map<MutableKey, String> map = new HashMap<>(); map.put(key, "Yes Album"); // The key mutates key.id = 90125; // Now you cannont retrieve the album System.out.println(map.get(key)); // Output: null

そうだね👉

 class ImmutableKey { private final int id; ImmutableKey(int newId) { this.id = newId; } @Override public int hashCode() { return this.id; } @Override public boolean equals(Object objectToCompare) { if (this == objectToCompare) return true; ImmutableKey that = (ImmutableKey) objectToCompare; return id == that.id; } } ImmutableKey key = new ImmutableKey(42); Map<ImmutableKey, String> map = new HashMap<>(); map.put(key, "Yes Album"); System.out.println(map.get(key)); // Output: Yes Album

検出 🔍

  • 半自動


ハッシュベースのコレクションでキーとして可変オブジェクトを使用しているかどうかを確認することで、この臭いを検出できます。


リンターや IDE 検査などの自動化ツールも、変更可能なキーにフラグを立てることができます。

タグ 🏷️

  • 可変性

レベル 🔋

  • 中級

なぜ全単射が重要なのか 🗺️

現実世界とプログラム間の一対一対応は、オブジェクトが表すべき関係を正確に反映することを保証するため重要です。


現実の世界では、キーは不変であることが多いです (ID、名前など)。


これらのキーを変更可能なオブジェクトとしてモデル化すると、現実世界とMAPPER内のプログラム間の 1 対 1 の対応が崩れます。


可変キーを使用してこの一対一性を破ると、マップの一貫性がなくなり、取得の失敗や予期しない動作が発生します。

AI世代🤖

AI ジェネレーターは、影響を考慮せずにキーとして可変オブジェクトを生成すると、この臭いを生み出す可能性があります。


AI ジェネレーターは原始的な強迫観念に悩まされているため、このようなことはめったに起こりません。

AI検出 🥃

AI ジェネレーターは、ハッシュベースのコレクションでの変更可能なオブジェクトの使用を分析し、潜在的な問題をフラグ付けする指示を使用して、この臭いを検出できます。


作成後にオブジェクトの状態を変更するfinalフィールドやメソッドのないクラスを探すように AI に指示できます。

ぜひお試しください!🛠

覚えておいてください:AIアシスタントは多くの間違いを犯します

適切な指示がなければ

具体的な指示

チャットGPT

チャットGPT

クロード

クロード

困惑

困惑

副操縦士

副操縦士

ジェミニ

ジェミニ

ディープシーク

ディープシーク

メタAI

メタAI

結論🏁

可変オブジェクトをキーとして使用すると、キーの状態とハッシュ コード間の契約が破られるリスクがあります。


この問題を回避するには、不変オブジェクトを使用します。

関係👩‍❤️‍💋‍👨

https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxxiv

https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxv

https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxiv

https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxxvi

https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xviii

https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxvi

https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xlii

詳細情報 📕

免責事項 📘

コードスメルは私の意見です。

クレジット🙏

UnsplashKathyryn Trippによる写真


プログラムの最も重要な特性は、それがユーザーの意図を達成するかどうかです。


CAR ホア



この記事は CodeSmell シリーズの一部です。