更改存储在集合中的对象的状态

时间:2013-01-31 09:35:28

标签: java object set

有没有什么好的建议如何处理存储在Sets中的可变对象?

某些对象可以根据其内部状态定义它们的相等性(和hashCode)。当这些对象存储在受控代码内外的集合中时,状态的突变可能会导致集合中的不一致。

是否有任何“最佳做法”可以避免或处理,除此之外不要这样做?

示例代码:

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);
 }

2 个答案:

答案 0 :(得分:3)

在某些时候,开发团队在处理只有在存储到数据库之前才得到密钥的实体集合时会遇到很多问题。他们的hashcode / equals取决于那个键...

我们提出的解决方案是这样的:

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

另一个想法是Set实现装饰HashSet,但我们很快就认定这会导致更长时间的问题。在大多数情况下,上述方法是由“框架”代码对开发人员透明地执行的,但我对这个解决方案仍然不是特别满意。

答案 1 :(得分:0)

设置界面不提供获取值的任何方法,并且有理由这样做。 Java Set API

所以它不期望你得到一个值,修改它然后再添加它。在你的代码中,你正在做的事情;您修改了存储在Set中的值。

理想情况下你应该避免它,但是如果你想修改Set中的任何对象,那么请执行以下步骤:

  1. 从集合
  2. 中删除对象
  3. 添加新的修改对象
  4. 这样就可以保证哈希码/相等合同。