我有一个Set对象,我使用这个集合来确保当我向它添加一个已经存在于集合中的元素时,它不会被添加。这是一个简单的部分,只需使用Set.add();
但是在完成此操作后,我需要引用Set中的对象。
我的本质意思是让.add()
不返回布尔值,但是您尝试添加的实际对象(如果未添加,则为集合中的对象)。是否已经有一个Set实现来执行此操作,还是我必须自己编写?
目前我使用了Set.add()
,如果它返回false,我使用迭代器来查找集合中的那个。虽然这有效,但我发现它很难看。特别是当使用HashSet实现时,它应该能够使用哈希码更快地找到对象。有什么想法吗?
数据:
foo bar 1 3 1 4 2 5
数据结构:
Set<Foo> totalFooSet
Set<Bar> totalBarSet
Foo:
sometype data
Set<Bar> barSet
栏:
sometype data
Set<Foo> fooSet
这有点像多对多的关系。
我不确定这里是否存在一些重大的设计缺陷,我已经和其他人一起看过了,我们无法弄清楚如何以不同的方式做到这一点。我喜欢使用HashMap的想法,所以我将创建一个子类并向其添加addAndReturn()函数。
答案 0 :(得分:5)
(正如@AlexR所说,我假设你想要一个 previous 对象的引用,它等于你现在想要添加的对象)
尝试使用具有与键和值相同的对象的HashMap,而不是使用Set。然后,您可以执行以下操作:
Foo objectToAdd = //obtained the normal way
Map<Foo,Foo> psuedoSet = //this is stored somewhere
Foo result = psuedoSet.get(objectToAdd);
if (result == null) {
pseudoSet.put(objectToAdd, objectToAdd);
result = objectToAdd;
}
return result;
答案 1 :(得分:4)
与Sean的答案(我赞成)相似,但可能更可重复使用。
public class HashMapBackedSet<T> extends HashMap<T,T>{
public T add( T toAdd ){
T existing = get( toAdd );
if( existing != null ){
return existing;
}
put( toAdd, toAdd );
return toAdd;
}
}
答案 2 :(得分:3)
如果我理解正确,如果您刚试图添加的元素已经包含在集合中,那么您需要已经在集合中的实例(等于添加的实例,但不一定相同)?
此行为由interners库的Google Guava提供:
Interner<Object> interner = Interners.newStrongInterner();
Object objectInSet = interner.intern(otherObject);
不幸的是,内部人员不提供任何其他方法,例如迭代其包含的值,因此可能无法使用它们作为集合替换。
另一个选项是HashMap<T, T>
,您可以在其中存储从每个对象到自身的映射。然后,您可以通过调用get()
轻松获取对已包含对象的引用。如果您不介意始终覆盖该对象,只需调用put()
,它将返回您想要的对象(以前存储的对象)。
答案 3 :(得分:0)
设置不能包含重复的条目。 set的目的不是为了做到这一点。
据我所知,您希望引用之前的对象,该对象与您现在尝试添加的对象相同。
您不必迭代该集合来查找此对象。只需用户oldObject = set.get(newObject)
。
此操作与按索引获取数组元素一样快。
答案 4 :(得分:-1)
在调用add?
时,将您的集合包装在一个返回该对象的类中