我有 Java 代码,它将函数应用于 HashSet 的每个元素。每个元素都必须 (1) 从 HashSet 中删除,(2) 进行处理,这会返回相同类型的结果(有时甚至是相同的对象实例),有时甚至会在集合中返回该类型的多个实例; (3)结果被替换到HashSet中。
我从原始 HashSet 中删除每个元素,处理它的元素直到其为空。我将通过处理对象返回的每个新实例放入新的 HashSet 中。完成后,我会丢弃旧的 HashSet 并继续使用新的 HashSet。我认为我必须这样做,因为否则,当我迭代 HashSet 的每个元素同时向其中添加元素时,我将面临无限循环的风险。 代码有点像这样。 Fct addToHashSet 向 newSet 添加 1 个或多个元素。
newSet= new HashSet< myObjectType >();
for (myObjectType s : origSet){
addToHashSet(newSet, process(s,message));
}
return newSet;
我的问题是:
1)我不断地创建和删除HashSets(这个处理调用很多)是不是效率低下?
2)如果是这样,是否有一种更好的、就地的方式来处理每个元素一次(我不想处理我刚刚添加的元素)而不创建新的 HashSet?
3) 如果答案是否定的,那么对于将哈希集的每个元素替换为单个实例的情况是否可以?该代码如下所示:
newSet= new HashSet< myObjectType >();
for (myObjectType s : origSet){
newSet .add(process(s,message));
}
return newSet;
最佳答案
如果您确实需要 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());
关于java - 这段Java代码可以变得更高效吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47422816/