如果我现在不仅要删除元素我的迭代点,还要删除另一个元素,我该怎么办?任务是写出总和达到某个值的对(它们存储在HashSet集中)。想法:遍历集合,找到总和到我需要的第二个元素,将它们写出并从集合中删除。我的意思是,如果我的集合是:[1,2,3]和int sum = 4,那么我迭代,找到元素1st:1,检查4 - 1 = 3,写出(1,3),然后我想从集合中删除1和3,以便只剩下{2}。我当然不能这样做:
while (itr.hasNext()) {
int elem = itr.next();
int toSum = sum - elem;
if (set.contains(toSum)) {
System.out.println("(" + elem + "," + toSum + ")");
}
itr.remove();
set.remove(toSum);
}
因为并发异常。我找到了解决方案:
while (itr.hasNext()) {
HashSet<Integer> notNeeded = new HashSet<Integer>();
int elem = itr.next();
if (notNeeded.contains(elem)) {
itr.remove();
}
else {
int toSum = sum - elem;
if (set.contains(toSum)) {
System.out.println("(" + elem + "," + toSum + ")");
notNeeded.add(toSum);
}
itr.remove();
}
}
但这看起来并不优雅和高效(特别是节省空间)。有没有更好的方法呢?
答案 0 :(得分:1)
我建议使用已使用值的第二个Set。然后,您可以决定是否在最后从原始集中删除它们。
Set<Integer> set = new HashSet<>(Arrays.asList(1,2,3,4,5,6));
int target = 7;
Set<Integer> used = new HashSet<>();
for (Integer value1 : set) {
if (used.contains(value1))
continue; // already processed
Integer value2 = target - value1;
if (! value2.equals(value1) && set.contains(value2)) {
used.add(value1);
used.add(value2);
System.out.println("(" + value1 + "," + value2 + ")");
}
}
set.removeAll(used); // optional
通过使其具有非破坏性,您可以将Set重新用于其他搜索:
private static void listPairs(Set<Integer> set, int target) {
System.out.print(target + ": ");
Set<Integer> used = new HashSet<>();
for (Integer value1 : set)
if (! used.contains(value1)) {
Integer value2 = target - value1;
if (! value2.equals(value1) && set.contains(value2)) {
used.add(value1);
used.add(value2);
System.out.print("(" + value1 + "," + value2 + ")");
}
}
System.out.println();
}
public static void main(String[] args) {
Set<Integer> set = new HashSet<>(Arrays.asList(1,2,3,4,5,6));
listPairs(set, 7);
listPairs(set, 6);
listPairs(set, 5);
}
<强>输出强>
7: (1,6)(2,5)(3,4)
6: (1,5)(2,4)
5: (1,4)(2,3)
答案 1 :(得分:0)
当然,由于并发异常,您无法在Set.remove()
内调用Iterator
,但您可以中断迭代并在之后将其删除。
Integer toSumFound = null;
while (itr.hasNext()) {
int elem = itr.next();
int toSum = sum - elem;
if (set.contains(toSum)) {
toSumFound = toSum;
System.out.println("(" + elem + "," + toSum + ")");
itr.remove();
break;
}
}
set.remove(toSumFound); //Check for nulls if needed