簡體   English   中英

遍歷集合-刪除其他元素

[英]iterating through collection - removing other element

如果我現在不僅要刪除迭代器指向的元素,還要刪除另一個元素,該怎么辦? 任務是寫出總計為某個值的對(它們存儲在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();
  }
}

但這看起來並不優雅高效(尤其是節省空間)。 有什么更好的方法嗎?

我建議使用已使用的值的第二個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)

好吧,由於並發異常,您當然不能在Iterator調用Set.remove() ,但是您可以中斷迭代並在之后將其刪除。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM