我有一个Java代码,它将函数应用于HashSet的每个元素。每个元素必须(1)从HashSet中删除,(2)处理,返回相同类型的结果(有时甚至是相同的对象实例),有时在集合中有多个这种类型的实例; (3)结果在HashSet中被替换。
我从原始HashSet中删除每个元素,处理它的元素直到它为空。我通过在新的HashSet中处理对象来放置返回的每个新实例。当我完成后,我丢弃旧的HashSet并继续使用新的HashSet。我认为我必须这样做,因为否则,当我迭代HashSet的每个元素同时还向其添加元素时,我冒着无限循环的风险。 代码有点像这样。 Fct addToHashSet向newSet添加一个或多个元素。
newSet= new HashSet< myObjectType >();
for (myObjectType s : origSet){
addToHashSet(newSet, process(s,message));
}
return newSet;
我的问题是:
1)通过不断创建和删除HashSets,我是否效率低下(这个处理被称为很多)?
2)如果是这样,是否有更好的,适当的方式来处理每个元素一次,(我不想处理我刚刚添加的元素)而不创建新的HashSet?
3)如果答案为否,那么在Hashset的每个元素被单个实例替换的情况下,它是否可以为圆顶?该代码看起来像这样:
newSet= new HashSet< myObjectType >();
for (myObjectType s : origSet){
newSet .add(process(s,message));
}
return newSet;
答案 0 :(得分:2)
如果您确实需要Set
的属性,
如果您的进程返回新实例,
而不是修改集合中的实例,
那你现在的解决方案没问题。
如果进程修改实例而不是返回新实例,
然后你可以改用forEach
方法:
origSet.forEach(item -> process(item));
如果您不需要Set
的属性,则可以使用Queue<>
代替:
int size = queue.size();
for (int i = 0; i < size; i++) {
queue.add(process(queue.poll()));
}
在此循环结束时,queue
的原始元素将全部消失,它将包含process
返回的新元素。
如果你真的需要一套替换旧套装的新套装, 然后你可以使用一个更流行的解决方案与流(在评论中指出@Simon):
newSet = origSet.stream().map(s -> process(s, message)).collect(Collectors.toSet());