Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 列表项之间的差异_Java_Arraylist - Fatal编程技术网

Java 列表项之间的差异

Java 列表项之间的差异,java,arraylist,Java,Arraylist,我有两张单子,一张和二张。 我必须找出ListOne中的所有元素,而ListOne中不存在这些元素。 同样地 我必须找出ListOne中不存在的ListTwo的所有元素 我下面的代码正在运行,但我认为可能有更好的方法 List<Long> listOne=...Some valid values; List<Long> listTwo=...Some valid values; List<Long> listTh

我有两张单子,一张和二张。 我必须找出ListOne中的所有元素,而ListOne中不存在这些元素。 同样地 我必须找出ListOne中不存在的ListTwo的所有元素

我下面的代码正在运行,但我认为可能有更好的方法

        List<Long> listOne=...Some valid values;
        List<Long> listTwo=...Some valid values;
        List<Long> listThree=new ArrayList<Long>();
        List<Long> listFour=new ArrayList<Long>();

    for (Long id: ListOne) {
        if(!listTwo.contains(id)){
            listThree.add(id);
        }
    }

    for (Long id: ListTwo) {
        if(!listOne.contains(id)){
            listFour.add(id);
        }
    }
List listOne=…一些有效值;
List listTwo=…一些有效值;
List listThree=新的ArrayList();
List listFour=新的ArrayList();
for(长id:ListOne){
如果(!listwo.contains(id)){
列表3.add(id);
}
}
for(长id:ListTwo){
如果(!listOne.contains(id)){
列表4.add(id);
}
}

以下内容适合您

List<Long> listOne =...Some valid values;
List<Long> listTwo =...Some valid values;

List<Long> listThree = new ArrayList<>(listOne);
List<Long> listFour = new ArrayList<>(listTwo);
listThree.removeAll(listTwo);
listFour.removeAll(listOne);
List listOne=…一些有效值;
List listTwo=…一些有效值;
List listThree=新的ArrayList(listOne);
List listFour=新的ArrayList(listTwo);
清单3.移除所有(清单2);
列表四。移除所有(列表一);
从java文档:

RemoveAll:从此列表中删除指定集合中包含的所有元素(可选操作)


作为Lino answer的替代方案,您还可以以功能性方式重写代码:

List<Long> listOneButListTwoElements = listOne.stream()
        .filter(l-> !listTwo.contains(l))
        .collect(Collectors.toList());


List<Long> listTwoButListOneElements = listTwo.stream()
        .filter(l-> !listOne.contains(l))
        .collect(Collectors.toList());
List listOneButListTwoElements=listOne.stream()
.filter(l->!listTwo.contains(l))
.collect(Collectors.toList());
List listTwoButListOneElements=listTwo.stream()
.filter(l->!listOne.contains(l))
.collect(Collectors.toList());

要真正提高效率,您可以这样做:

Set<Long> setOne = new HashSet<>(listOne);
Set<Long> setTwo = new HashSet<>(listTwo);

List<Long> listThree = listOne.stream()
        .filter(e -> !setTwo.contains(e))
        .collect(Collectors.toList());
List<Long> listFour = listTwo.stream()
        .filter(e -> !setOne.contains(e))
        .collect(Collectors.toList());

否定谓词有多种方法。这里不必赘述,它已经存在。

可能答案:可能重复的可能重复的也请注意,对于第一个列表的长度
m
和第二个
n
,这将具有
m*n
的时间复杂度。如果列表很短,没问题。然而,长列表可能会带来麻烦。您正在描述一个集合代数运算,差分。您应该使用java.util.Set实现。如果您可以使用Guava,com.google.common.collect.Sets是一个很好的类,其中包含Sets实用程序。很高兴同时提到这两个实用程序,但OP要求的是
removeAll
removeAll()
确实简化了处理过程。更好,但您的代码修改有错误。您对现有列表执行操作。@davidxxx哦,是的,我编辑列表时删除了太多内容。谢谢是的,很好。尽管如此,它仍然在循环的每一步迭代一个列表。Vlasec是正确的。这是O(n²)。最好从每个列表中创建一个临时集合,并使用该集合而不是
.contains(l)
calls中的列表。是的,我自己写了一个答案。不过,如果您能够编写
filterOut(setTwo::contains)
:)@Vlasec,那么流的部分几乎没有什么不同。“请求反向过滤的直接方法真的不存在了。”Vlasec和Klitos Kyriacou说得对。关于复杂性的缺点,这是对的,但只有当您有一个包含许多元素的列表时,它才可能成为一个问题。OP没有指定这一点。对于大列表,这是完美的,但是对于小列表,我猜这可能有点过分了。改进+1。但我同意利诺的观点。引入额外的中间变量在某种程度上击败了函数式编程范式。我同意,如果你可以声明性地编写它,而不需要额外的变量,看起来会更好。我经常喜欢写这样的代码。现在我想起来了,很遗憾没有所谓的
filterOut
或类似的
filterOut
的对立面,那么你可以像
那样将集合放在里面。filterOut(新的HashSet(listOne)::contains)
:)不会为流列表中的每个元素创建一个新的HashSet吗?@KlitosKyriacou实际上不是。它会的,如果它在lambda里面的话。但我写它的方式是,它是一个方法引用,它引用了新对象的方法
包含的方法
List<Long> listThree = listOne.stream()
        .filter(not(new HashSet(listTwo)::contains))
        .collect(Collectors.toList());