Java 8 流。除其他元素外的所有元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35512258/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 00:12:28  来源:igfitidea点击:

Java 8 stream. all elements EXCEPT other elements

javajava-8java-stream

提问by Beta033

I'm interested in identifying an approach that returns a list of elements excluding the elements in another list.

我有兴趣确定一种返回元素列表的方法,该列表不包括另一个列表中的元素。

for example

例如

List<Integer> multiplesOfThree = ... // 3,6,9,12 etc
List<Integer> evens = ... // 2,4,6,8 etc
List<Integer> others = multiplesOfThree.except(evens) // should return a list of elements that are not in the other list

how do you do this? i found an approach that's a bit clunky and difficult to read....

你怎么做到这一点?我发现了一种有点笨拙且难以阅读的方法......

multiplesOfThree.stream()
.filter(intval -> evens.stream().noneMatch(even -> even.intValue() == intval.intValue()))

回答by rgettman

You can use Stream's filtermethod, passing a Predicatethat ensures that the element doesn't exist in evens.

您可以使用Streamfilter方法,传递Predicate确保元素不存在于evens.

List<Integer> others = multiplesOfThree.stream()
        .filter(i -> !evens.contains(i))
        .collect(Collectors.toList());

But assuming you have a mutable List(e.g. ArrayList), you don't even need streams, just Collections's removeAllmethod.

但是假设你有一个可变的List(例如ArrayList),你甚至不需要流,只需要Collections's removeAllmethod

multiplesOfThree.removeAll(evens);

回答by fabian

You could use

你可以用

multipleOfThree.stream()
               .filter(((Predicate<Integer>) evens::contains).negate())

or more efficient for big evenlists

或者对于大even列表更有效

HashSet<Integer> evenSet = new HashSet<>(even);
multipleOfThree.stream()
               .filter(((Predicate<Integer>) evenSet::contains).negate())

回答by Todd

There are a few solutions.

有几种解决方案。

First, without using streams, you can just create a new list and remove all elements from another collection from it...

首先,不使用流,您只需创建一个新列表并从中删除另一个集合中的所有元素...

final List<Integer> multiplesOfThree = Arrays.asList(3,6,9,12);
final List<Integer> evens = Arrays.asList(2,4,6,8,10,12);
final List<Integer> others1 = new ArrayList<>(multiplesOfThree);
others1.removeAll(evens);

Another solution would be to pass the stream through a filter():

另一种解决方案是通过过滤器()传递流:

final List<Integer> others2 = multiplesOfThree
     .stream()
     .filter(x -> !evens.contains(x))
     .collect(Collectors.toList());

(You may want to consider making evensa Setin this case).

(在这种情况下,您可能需要考虑制作evens一个Set)。

And finally, you could modify the logic above to represent the "evens" as a function rather than a collection of all even numbers. This is essentially the same as above, but you don't have to have a second collection.

最后,您可以修改上面的逻辑,将“偶数”表示为一个函数,而不是所有偶数的集合。这与上面的基本相同,但您不必有第二个集合。

final List<Integer> others3 = multiplesOfThree
    .stream()
    .filter(x -> x % 2 != 0)
    .collect(Collectors.toList());