如何在迭代此 HashSet 时向 HashSet 添加元素?

How to add element to a HashSet while iterating this HashSet?

我有一个如下的用例:

SET is a Set of Integer with size N
for i in SET (I mean only iterate the Set of size N at start point):
    if i + 7 not in SET:
        SET.add(i + 7)

return SET

如何使用Java HashSet实现这个,除了使用辅助list/set来存储需要插入的元素?

@lucasvw 在这里避开了潜在的问题——你需要以某种方式区分原始值和你添加的值,否则,循环将 运行 无限期地(或者,至少,直到值溢出太多,所以它们开始重复自己)。

最好的方法是确实有一个辅助集来保存您要添加的所有值:

Set<Integer> aux = original.stream().map(i -> i + 7).collect(Collectors.toSet());
original.addAll(aux);

在遍历 Set 实例的内容时不可能向其添加内容;当使用 foreach 循环(for( var e : set ) 表示法)时,不允许修改,而当使用显式迭代器(for( var i = set.iterator(); i.hasNext(); ) … 表示法)时,可以调用 i.remove() 来摆脱当前元素。但是在这种情况下添加新元素仍然不起作用。

此行为为所有 Java 集合 class 共享,尽管 List 知道一个特殊的迭代器 class、ListIterator,它也允许添加通过调用 i.add() 输入(符号 for( var i = list.listIterator(); i.hasNext(); ) …)——感谢@lucasvw 提醒我。

如果您不想自己制作副本,Java 可以为您制作副本:https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CopyOnWriteArraySet.html。它不会更快或任何神奇的东西,但你可以迭代 "the original" 并同时修改。

但是,如果您想要一些高效的东西,大概是用新元素创建另一个 Set,最后 addAll() 它们。根据集合的大小,跳过包含检查并留待合并可能会更快。

BitSet 及其 or() 运算如果您的数字是非负数且幅度较小,也可能需要注意。