假设我的应用程序中有这种类型:
public class A { public int id; public B b; public boolean equals(Object another) { return this.id == ((A)another).id; } public int hashCode() { return 31 * id; //nice prime number } }
和一个结构.现在,我有一个类型的对象,并希望执行以下操作:Set
>
A
如果我A
在集合中,请更新其字段b
以匹配我的对象.
否则,将其添加到集合中.
所以检查它是否在那里很容易(contains
),并且添加到集合也很容易.我的问题是:如何获得更新对象的句柄?接口Set
没有get
方法,我能想到的最好的方法是删除集合中的对象并添加我的对象.另一种,更糟糕的是,替代方法是使用迭代器遍历集合以尝试定位对象.
我很乐意接受更好的建议......这包括有效使用其他数据结构.
Yuval = 8-)
编辑:谢谢大家回答...不幸的是我不能'接受'这里的最佳答案,建议使用a Map
,因为为此目的而根本改变集合的类型只会有点极端(这个集合是已经通过Hibernate映射...)
由于Set只能包含一个对象实例(由equals和hashCode方法定义),因此只需将其删除然后添加即可.如果已经有一个,那么另一个将从Set中删除并替换为您想要的那个.
我有类似的代码 - 我正在缓存对象,以便在gui上的一堆不同的地方出现一个特定的对象,它总是相同的.在这种情况下,不是使用Set我使用Map,然后我得到更新,我从Map检索它并在适当的位置更新它而不是创建一个新实例.
然后将ID(即使它也存储在A
!中)映射到对象.所以存储新是这样的:
A a = ...; Mapmap = new HashMap (); map.put( a.id, a );
您的完整更新算法是:
public static void update( Mapmap, A obj ) { A existing = map.get( obj.id ); if ( existing == null ) map.put( obj.id, obj ); else existing.b = obj.b; }
但是,它可能更简单. 我假设你的领域多于你所提供的领域A
. 如果不是这种情况,只是使用a Map
实际上是你想要的,那么它就会崩溃为零:
Mapmap = new HashMap (); // The insert-or-update is just this: map.put( id, b );
如果您使用Set,我认为您不能比使用remove/add更容易.
set.remove(a); set.add(a);
如果找到匹配的A,它将被删除,然后你添加新的,你甚至不需要if (set.contains(A))
条件.
如果您有一个具有ID和更新字段的对象,并且您并不真正关心该对象的任何其他方面,请将其抛出并替换它.
如果你需要对匹配该ID的A做任何其他事情,那么你将不得不遍历Set以找到它或使用不同的Container(如Jason建议的Map).