2009-03-11 9 views
6

私のアプリケーションには、ある種類のすべてのオブジェクトが他の種類のオブジェクトにちょうど1つの対応するオブジェクトを持つ2種類のオブジェクトがあります。Javaのマップキーとして任意のオブジェクトを使用することにはどのような欠点がありますか?

この関係を把握するための明らかな選択肢は、HashMapのようにMap<type1, type2>です。しかし何とか、私は疑わしい。マップ内のキーとしてオブジェクトを使用し、それを渡したり、別のコレクションに座ったりして、マップからパートナーをいつでも取得できますか?

オブジェクトが作成された後、私が渡しているのは識別子ですよね?おそらく問題はないでしょう。キーをシリアル化してデシリアライズするとどうなりますか?

その他の警告はありますか?私は自分自身を生成する数字のように、オブジェクトのペアを関連付けるために何か他のものを使うべきですか?

答えて

22
  1. キーは、それが理想的なキー
  2. としてキーとして使用任意のオブジェクトを使用している間、それは.hashCode()値です変更する任意の方法で変更してはならない
  3. 正しく.equals().hashCode()を実装するための重要なニーズHashMapの場合は変更できません。これにより、自動的に2.が常に確実に保持されます。
  4. GCされる可能性のあるオブジェクトは、キーや値として使用されたときに保持されます。
0

オブジェクトにはマップキーを使用できます。ここで重要なことは、マップキーとして使用されるすべてのオブジェクトに対して.equals()および.hashCode()をオーバーライドすることを確認することです。

これを行う理由は、そうでない場合、equalsはオブジェクトの等価として理解され、「等しい」マップキーを見つける唯一の方法は元のオブジェクトのハンドルを持つことです自体。

ハッシュコードをオーバーライドするには、equalsと一致する必要があるためです。これは、あなたが定義したオブジェクトが等しくハッシュされるようにするためです。

0

障害ポイントは、ハッシュコード関数と等価関数です。一貫性のある正しい戻り値が得られない場合、Mapは奇妙な動作をします。 Effective Javaには全体のセクションがあり、非常に強く推奨されています。

7

私は1つ 種類のすべてのオブジェクトは、他の種類の オブジェクトを対応する正確にものを持っている私の アプリケーション内のオブジェクトの2種類があります。

これは実際にはhas-a関係のように聞こえるため、単純な属性を使用して実装できます。

+0

私は同意します。残りの質問は他の人にとってまだ役立つかもしれません。 (何らかの理由で代替できない場合@OPのために) –

+0

@ saau私はあなたに同意します。私はこの特定の文脈で属性の適用可能性を指摘しています。 –

1

標準マップを使用することもできますが、そうすることでマップ内のオブジェクトへの強い参照が維持されます。オブジェクトが別の構造体で参照されていて、それらをリンクするだけのマップが必要な場合は、WeakHashMapの使用を検討してください。

また、equalsおよびhashCodeをオーバーライドする必要はありません。オブジェクトの複数のインスタンスを等価とみなさなければならない場合を除きます...

1

マップ内のオブジェクトをキーとして使用したり、渡したり、別のコレクションに座ったりして、いつでもマップからパートナーを取得できますか?

はい、ここに問題はありません。

オブジェクトが作成された後、私が渡しているのは識別子です。おそらく問題はないでしょう。キーをシリアル化してデシリアライズするとどうなりますか?

そうです、あなたは参照を渡すだけです - それらはすべて同じ実際のオブジェクトを指します。オブジェクトをシリアル化または逆シリアル化すると、新しいオブジェクトが作成されます。ただし、オブジェクトがequalsおよびhashCodeを正しく実装している場合は、新しい非直列化オブジェクトを使用してマップからアイテムを取得することができます。

その他の警告はありますか?私は自分自身を生成する数字のように、オブジェクトのペアを関連付けるために何か他のものを使うべきですか?

警告としては、オブジェクトがマップ内にある間にオブジェクトのhashCodeが変更されるような変更はできません。

3

それはあなたが選択したマップの実装に依存します:

  • HashMapののequals()のhashCode()を使用しています。デフォルトでは(Objectの場合)、これらはオブジェクトIDに基づいています。これは、シリアル化/逆シリアル化しない限り正常に動作します。オブジェクトの内容に基づいてequals()とhashCode()を適切に実装することで、ハッシュマップのキーである間に変更しない限り問題は発生しません。

  • TreeMapは、compareTo()を使用します。デフォルトの実装は存在しないため、実装する必要があります。上記のhashCode()とequals()の実装と同じ制限が適用されます。

0

GoogleコレクションのBiMapと考えられます。

関連する問題