迭代时从HashSet中删除元素

时间:2015-04-22 16:42:47

标签: java algorithm hashset concurrentmodification

假设我有HashSet

[1, 2, 3, 4, 5, 6]

我希望以这样的方式迭代它,对于给定的总和,比如6,在迭代元素时,如果我在Set中找到2个元素,其中sum = 6,我想删除另一个。 E. g。,如果我迭代超过1,我应该删除5.我试图做这样的事情:

HashSet<Integer> hs = new HashSet(arr);
int sum = 6;
for(int num : hs) {
    if(hs.contains(sum - num)) {
        hs.remove(sum - num);
    }
}

显然它会抛出java.util.ConcurrentModificationException。另一种方法是使用迭代器,但它会删除当前元素,并且不会将任何其他元素作为参数。我还能用什么?

更新:我知道使用附加设置和所有设备的技巧。如果可能的话,我只想要一个非常优化的解决方案,而不会增加时间和空间的复杂性。

2 个答案:

答案 0 :(得分:3)

保留您找到的一组正在运行的数字。

这将允许您使用一次通过解决方案。

从空的运行集开始,遍历您的数字集。对于迭代的每个元素,如果它的sum-compliment在集合中,则从迭代器中删除它。否则,将其添加到正在运行的集合中。

HashSet<Integer> hs = new HashSet(arr);
HashSet<Integer> running = new HashSet();
int sum = 6;
Iterator<Integer> iter = hs.iterator();
while (iter.hasNext()) {
    int num = iter.next();
    if (running.contains(sum - num)) {
        iter.remove();
    } else {
        running.add(num);
    }
}

此代码将修改原始HashSet,并且HashSet将在代码块的末尾包含相同的内容。在这种情况下,最好只使用代码末尾的running集,而不是修改原始代码。这将使这段代码更加灵活和可重用。

答案 1 :(得分:2)

您可以使用排序列表。 首先按递增顺序对数字进行排序。然后你将2个迭代器放在第一个元素中,将另一个放在最后一个元素中。然后在每一步中,如果迭代器下的2个项的总和小于你想要的数,你应该增加第一个迭代器,如果它的重量减去你应该减少第二个迭代器,如果它等于你想要的你选择它们并增加第一个和减少第二个迭代器。

它比套装更快!