从另一个arrayList中减去一个arrayList

Mil*_*lic 20 java

我有两个arrayLists,我试图从另一个"减去"一个arrayList.例如,如果我有一个arrayList [1,2,3]并且我试图减去[0,2,4],则得到的arrayList应该是[1,3].

List<Integer> a = new ArrayList<>(Arrays.asList(1, 2, 3));
List<Integer> b = Arrays.asList(0, 2, 4);
subtract(a,b) // should return [1,3]
Run Code Online (Sandbox Code Playgroud)

这是我的代码.

//returns a new IntSet after subtracting a from b
// .minus().toString()
ArrayList<Integer> minusArray = new ArrayList<Integer>();

    minusArray.addAll(array1);

    for(int i =0; i< minusArray.size(); i++){
        for(int j = 0; j < array2.size(); j++){
            if(minusArray.get(i).equals(array2.get(j))){
                minusArray.remove(i);
                if(i == 0){
                    ;
                }
                else if(j == 0){
                    ;
                }
                else{
                    i = 0;
                    j = 0;
                }
            }
            else{}
        }
    }

return minusArray;
Run Code Online (Sandbox Code Playgroud)

我的代码在某些情况下有效,比如if arrayList1 = [4,6],arrayList2 = [6]它会给我一个结果[4].但是,如果我尝试像[1,2,4][0,4,8]

我得到这个例外:

java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
    at java.util.ArrayList.rangeCheck(Unknown Source)
    at java.util.ArrayList.get(Unknown Source)
    at IntSet.minus(IntSet.java:119)
    at IntSetDriver.main(IntSetDriver.java:62)
Run Code Online (Sandbox Code Playgroud)

这是我提出的代码.我已经完成了测试并且对我来说我认为它应该可行.用户输入这些arrayLists并且它们是预先排序的,我也不知道Hash或big-O.

ArrayList<Integer> minusArray = new ArrayList<Integer>();

    minusArray.addAll(array1);

    for(int i =0; i< minusArray.size(); i++){
        for(int j = 0; j < array2.size(); j++){
            if(minusArray.get(i).equals(array2.get(j))){
                minusArray.remove(i);
            }
            else{}
        }
    }

return minusArray;
Run Code Online (Sandbox Code Playgroud)

Mar*_*ips 42

有什么理由你不能简单地使用List.removeAll(List)?

    List<Integer> one = new ArrayList<Integer>();
    one.add(1);
    one.add(2);
    one.add(3);
    List<Integer> two = new ArrayList<Integer>();
    two.add(0);
    two.add(2);
    two.add(4);
    one.removeAll(two);
    System.out.println(one);

    result: "[1, 3]"
Run Code Online (Sandbox Code Playgroud)

  • `removeAll(2)` 将删除所有出现的 `2`,这不是通常定义的减法。通常它意味着仅在出现“2”时才删除。正确的?见 /sf/answers/3459079361/ (2认同)

Hir*_*rak 34

尝试使用org.apache.commons.collections.CollectionUtils类的subtract方法.

返回包含-b的新Collection.返回集合中每个元素e的基数将是e的基数,减去b中e的基数,或者为零,以较大者为准.

CollectionUtils.subtract(java.util.Collection a,java.util.Collection b)

来自Apache Commons Collections

  • @kukis CS 251将成为某大学的第二年计算机科学课程. (2认同)

i_a*_*ero 14

如果您打算使用Java8,您还可以使用流:

List<Integer> list1 =  Arrays.asList(1, 2, 3);
List<Integer> list2 =  Arrays.asList(1, 2, 4, 5);
List<Integer> diff = list1.stream()
                          .filter(e -> !list2.contains(e))
                          .collect (Collectors.toList()); // (3)
Run Code Online (Sandbox Code Playgroud)

这个答案不会操纵原始列表,如果这是我们可以使用的意图remove.我们也可以使用forEach(默认方法Iterator)或使用过滤器流.

  • @jschnasse它返回两个列表之间的差异,是的,它是减法.这里的意图是返回结果而不是操纵原始列表.如果我们想从原始列表中删除,那么我们可以使用删除. (7认同)

Yuv*_*val 7

遍历minusArray使用索引是一种方法,但我建议您使用该contains(Object)方法,这将允许您使用remove(Object)该特定元素array2.

当然,总会有removeAll(Collection)几乎所有你需要的东西......


Con*_*Del 5

您的问题是在您的 minusArray.remove(...) 调用中,您可能会缩小 minusArray 的大小。要解决此问题,请从 array.size() - 1 开始并倒数到 0

检查一下-即使那样也无法解决。您需要颠倒循环的顺序


Nic*_*las 5

您可以使用org.apache.commons.collections.ListUtils,只用一行就可以完成所有操作=)

List resultList = ListUtils.subtract(list, list2);
Run Code Online (Sandbox Code Playgroud)