1

Sets に保存されている変更可能なオブジェクトを処理する方法について何か良いアドバイスはありますか?

一部のオブジェクトは、内部状態に基づいて等価 (および hashCode) を定義する場合があります。このようなオブジェクトが Set に格納されている場合、制御されたコードの内外で、状態の変化によって Set の不整合が生じる可能性があります。

それを回避または対処するための「ベストプラクティス」はありますか?

コード例:

static class A {
   String s;
   public boolean equals(Object o) {
      return s.equals(((A)o).s);
   }
   public int hashCode() { 
      return s.hashCode();
   }
   public String toString() {
      return s;
   }

}

public static void main(String[] args) {
  A a0 = new A();
  a0.s = "Hello";
  A a1 = new A();
  a1.s = "World";

  HashSet<A> set = new HashSet<A>();
  set.add(a0);
  set.add(a1);

  System.out.println(set);

  a0.s = "World";

  System.out.println(set);
 }
4

2 に答える 2

3

ある時点で、開発チームは、データベースに保存される前にキーのみを取得したエンティティのコレクションを操作するときに、この問題を頻繁に抱えていました。それらのハッシュコード/等しいはそのキーに依存していました...

私たちが思いついた解決策は、次のようなものでした。

public static <P> void rearrange(Set<P> set) {
    HashSet<P> temp = new HashSet<P>();
    temp.addAll(set);
    set.clear();
    set.addAll(temp);
}

もう1つのアイデアは、HashSetを装飾するSetの実装でしたが、これが長期的にはより多くの問題を引き起こすとすぐに判断しました。ほとんどの場合、上記のメソッドは開発者に対して透過的に「フレームワーク」コードによって実行されますが、私はまだこのソリューションに特に満足していません。

于 2013-01-31T09:46:19.623 に答える
0

Setインターフェイスは、値を取得するためのメソッドを提供していません。それには理由があります。 Java セット API

したがって、値を取得して変更し、再度追加することは想定していません。あなたのコードでは、それがあなたがしていることです。Set に保存されている値を変更しました。

したがって、理想的には回避する必要がありますが、 Set 内のオブジェクトを変更する場合は、以下の手順を実行します。

  1. セットからオブジェクトを削除
  2. 新しい変更されたオブジェクトを追加する

このようにして、ハッシュコード/等価コントラクトが保証されます。

于 2013-01-31T09:55:28.733 に答える