2015-12-21 130 views
-2

如何刪除Java中另一個列表中存在的列表元素?

List<String> listOne = new ArrayList<String>(); 
listOne.add("3"); 
listOne.add("11"); 
listOne.add("20");` 

List<String> listTwo = new ArrayList<String>(); 
listTwo.add("1"); 
listTwo.add("2"); 
listTwo.add("3"); 
listTwo.add("6-11"); 
listTwo.add("18-20"); 

我想從存在於listOnelistTwo元素刪除。在此示例中,應刪除的值爲:36-1118-206-11,因爲在listOne中,我們的值爲1118-20的值相同。

如果可以的話,你能幫助我嗎?我不知道如何解決它。由於其刪除規則,這與其他人不一樣。否則,來自其他類似問題的其他答案並不能解決問題。

+1

你真的意味着你存儲在報名截止範圍?這聽起來像是將新範圍(18,20)這樣的實例存儲在列表中,而不是字符串更合適。 –

+0

由於這些是「String」的列表,因此您的意思是從'listTwo'中刪除任何值,其中'listOne'的值是一個子字符串,例如使用'contains()'? – Andreas

+0

如果這些應該是數字和數字範圍,請不要使用String。另外,如果你從'6-11'中刪除'11',不應該變成'6-10'嗎? – Andreas

回答

1

評論表明,只有明確列出的值應該引起被移除的元素,如:

listOne listTwo    Action 
"1"  "1", "3-9", "11" remove "1", but not "11" 
"2"  "1", "3-9", "11" do nothing 
"3"  "1", "3-9", "11" remove "3-9" 
"4"  "1", "3-9", "11" do nothing (3-9 is not a range) 

所以,按照這種怪異的邏輯,這裏有一個例子:

public static void main(String[] args) { 
    // should remove 3, 6-11, 18-20 
    System.out.println(remove(Arrays.asList("3", "11", "20"), 
           new ArrayList<>(Arrays.asList("1", "2", "3", "6-11", "18-20")))); 
    // should remove 2, not remove 6-11 (not a range), and not remove 18-20 (8 is not 18, 2 is not 20) 
    System.out.println(remove(Arrays.asList("2", "8"), 
           new ArrayList<>(Arrays.asList("1", "2", "3", "6-11", "18-20")))); 
} 
private static List<String> remove(List<String> listOne, List<String> listTwo) { 
    for (Iterator<String> listIter = listTwo.iterator(); listIter.hasNext();) { 
     String value = listIter.next(); 
     if (shouldRemove(value, listOne)) 
      listIter.remove(); 
    } 
    return listTwo; // for easy of use 
} 
private static boolean shouldRemove(String value, List<String> listOne) { 
    int idx = value.indexOf('-'); 
    if (idx == -1) { 
     for (String ref : listOne) 
      if (ref.equals(value)) 
       return true; 
    } else { 
     String value1 = value.substring(0, idx); 
     String value2 = value.substring(idx + 1); 
     for (String ref : listOne) 
      if (ref.equals(value1) || ref.equals(value2)) 
       return true; 
    } 
    return false; 
} 

輸出

[1, 2] 
[1, 3, 6-11, 18-20] 
+0

這個例子的工作更加正確。非常感謝。 – Arsench

1
public class Test { 
public static void main(String[] args) { 
    List<String> listOne = new ArrayList<String>(); 
    listOne.add("3"); 
    listOne.add("11"); 
    listOne.add("20"); 

    List<String> listTwo = new ArrayList<String>(); 
    listTwo.add("1"); 
    listTwo.add("2"); 
    listTwo.add("3"); 
    listTwo.add("6-11"); 
    listTwo.add("18-20"); 

    List<String> thirdList = new ArrayList<String>(); 

    for (String secondItem : listTwo) { 
     boolean match = false; 
     for (String firstItem : listOne) { 
      if(secondItem.contains(firstItem)) { 
       match = true; 
      } 
     } 
     if(!match) { 
      thirdList.add(secondItem); 
     } 
    } 
    for (String string : thirdList) { 
     System.out.println(string); 
    } 
} 

} 
+0

如果listOne有一個「1」元素,這段代碼將刪除「1」,「6-11」和「18-20」。我不相信(在這裏猜測)OP想要那樣。 – Andreas

+0

好點,問題可以簡單地通過分裂 - 然後比較來修改。在編輯之前等待確認。 –

+0

這就是我所設想的,並在我的答案中實現。正如你所說,我們會看到OP真正想要的,在500個問題之後引發任何可能的問題。 – Andreas

0
public static void main(String[] args) { 

     List<String> listOne = new ArrayList<>(); 
     listOne.add("3"); 
     listOne.add("11"); 
     listOne.add("20"); 

     List<String> listTwo = new CopyOnWriteArrayList<>(); 
     listTwo.add("1"); 
     listTwo.add("2"); 
     listTwo.add("3"); 
     listTwo.add("6-11"); 
     listTwo.add("18-20"); 

     listOne.stream().forEach(value -> { 
     listTwo.stream().filter(value2 -> (value2.contains(value))).forEach(value2 -> { 
      String[] minMax = value2.split(value2); 
      if (minMax.length == 1 && value2.equals(value)) { 
       listTwo.remove(value2); 
      } else if (minMax.length == 2) { 
       int intValue2 = Integer.parseInt(value2); 
       int min = Integer.parseInt(minMax[0]); 
       int max = Integer.parseInt(minMax[1]); 
       if (intValue2 >= min && intValue2 <= max) { 
        listTwo.remove(value2); 
       } 
      } 
     }); 
     }); 

     listTwo.stream().forEach(System.out::println); 
} 

Lambda Filtering Collections

What is CopyOnWriteArrayList?

+0

如果listOne有一個「1」元素,這段代碼將刪除「1」,「6-11」和「18-20」。我不相信(在這裏猜測)OP想要那樣。 – Andreas

+0

我編輯了我的答案。 – LowLevel

+0

目前還不清楚listTwo是否包含一個條,代表一個光盤(間隔)或者只是兩個不同的數字...... – LowLevel

0
List<String> listOne = new ArrayList<String>(); 
    listOne.add("3"); 
    listOne.add("11"); 
    listOne.add("20"); 
    List<String> listTwo = new ArrayList<String>(); 
    listTwo.add("1"); 
    listTwo.add("2"); 
    listTwo.add("3"); 
    listTwo.add("6-11"); 
    listTwo.add("18-20"); 

    List<String> values = new ArrayList<>();  // to store matched Strings 

    for (String s : listTwo) { 
     String strs[] = new String[2]; 
     if (s.contains("-")) { 
      strs = s.split("-");     // check for Strings 
     } 
     if (listOne.contains(s) 
       || listOne.contains(strs[0]) 
       || listOne.contains(strs[1])) { 
      values.add(s);      // save the value to a list 
     } 

    } 
    listTwo.removeAll(values); 
相關問題