java流之间的操作

java流之间的操作,java,java-8,java-stream,Java,Java 8,Java Stream,我正试图找到一种最快、也不太复杂的方法来对JavaSE8流执行一些并集/排除/交集操作 我正在这样做: Stream<String> fruitStream = Stream.of("apple", "banana", "pear", "kiwi", "orange"); Stream<String> fruitStream2 = Stream.of("orange", "kiwi", "melon", "apple", "watermelon"); //Trying

我正试图找到一种最快、也不太复杂的方法来对JavaSE8流执行一些并集/排除/交集操作

我正在这样做:

Stream<String> fruitStream = Stream.of("apple", "banana", "pear", "kiwi", "orange");
Stream<String> fruitStream2 = Stream.of("orange", "kiwi", "melon", "apple", "watermelon");

//Trying to create exclude operation
fruitStream.filter(
    item -> !fruitStream2.anyMatch(item2 -> item2.equals(item)))
.forEach(System.out::println);
// Expected result: fruitStream - fruitStream2: ["banana","pear"]
Stream fruitStream=Stream.of(“苹果”、“香蕉”、“梨”、“猕猴桃”、“橙子”);
溪流水果溪流2=溪流(“橙色”、“猕猴桃”、“甜瓜”、“苹果”、“西瓜”);
//正在尝试创建排除操作
水果流过滤器(
item->!fruitStream2.anyMatch(item2->item2.equals(item)))
.forEach(System.out::println);
//预期结果:果流-果流2:[“香蕉”、“梨”]
我得到以下例外情况:

java.lang.IllegalStateException:流已被操作或关闭

如果我能做这个手术,我就可以发展我自己,其他的,联合,交叉等等

因此,这两点是:

1) 在这个解决方案中,我做错了什么来获得那个异常

2) 是否有一种不太复杂的方式在两个流之间执行操作

注意


我想使用流来了解它们。不想将它们转换为数组或列表

在这个解决方案中,我做错了什么来获得那个异常

您不能多次使用同一
,在这里,您使用
水果流2
的次数与
水果流

是否有一种不太复杂的方式在两个流之间执行操作

您可以将第二个
转换为

Stream<String> fruitStream = Stream.of("apple", "banana", "pear", "kiwi", "orange");
Set<String> fruitSet = Stream.of("orange", "kiwi", "melon", "apple", "watermelon")
    .collect(Collectors.toSet());

fruitStream.filter(item -> !fruitSet.contains(item)).forEach(System.out::println);

第一次
项目->!任何匹配(item2->item2.equals(item))
执行时,它将使用
groutstream2
FroothStream2
不能再次用于筛选
FroothStream1
中的第二项

与其使用第二个流,为什么不创建一个
Set
并使用
contains

Set<String> otherFruits = new HashSet<>(); // Add the fruits.
fruitStream.filter(f -> !otherFruits.contains(f)).forEach(System.out::println);
Set otherFruits=new HashSet();//加入水果。
fruitStream.filter(f->!otherFruits.contains(f)).forEach(System.out::println);

流是只执行一次的内部迭代/处理。这是一个非常有限的领域

Supplier<Stream<String>> fruitStream2S = () ->
        Stream.of("orange", "kiwi", "melon", "apple", "watermelon");

fruitStream.filter(item -> !fruitStream2s.get().anyMatch(item2 -> item2.equals(item)))
    .forEach(System.out::println);
Supplier-stream2s=()->
“橘子”、“猕猴桃”、“甜瓜”、“苹果”、“西瓜”等;
filter(item->!fruitStream2s.get().anyMatch(item2->item2.equals(item)))
.forEach(System.out::println);

这是不高效的。

这有点傻,它不会给您带来很好的性能,但它确实满足了您不()创建数组或列表的要求:

public static void main(String[] args) {
    new Object() {
        Stream<String> fruitStream = Stream.of("apple", "banana", "pear", "kiwi", "orange");
        Stream<String> fruitStream2 = Stream.of("orange", "kiwi", "melon", "apple", "watermelon");
        {
            fruitStream2.forEach(f -> fruitStream = fruitStream.filter(Predicate.isEqual(f).negate()));
            fruitStream.forEach(System.out::println);
        }
    };
}
编辑一种(稍微)更直接的方法:

public static void main(String[] args) {
    Stream<String> fruitStream = Stream.of("apple", "banana", "pear", "kiwi", "orange");
    Stream.of("orange", "kiwi", "melon", "apple", "watermelon")
            .map(Predicate::isEqual)
            .reduce(Predicate::or)
            .map(Predicate::negate)
            .map(fruitStream::filter)
            .orElse(fruitStream)
            .forEach(System.out::println);
}
publicstaticvoidmain(字符串[]args){
溪流水果溪流=溪流(“苹果”、“香蕉”、“梨”、“猕猴桃”、“橙子”);
“橘子”、“猕猴桃”、“甜瓜”、“苹果”、“西瓜”等水果流
.map(谓词::isEqual)
.reduce(谓词::或)
.map(谓词::否定)
.map(水果流::过滤器)
.orElse(水果流)
.forEach(System.out::println);
}

“不想将它们转换为数组或列表”您可能不想这样做,但不会有其他解决方案不涉及在集合中存储一个流。您意识到varargs会隐式为您创建一个数组,对吗?如果您想忽略
stream.of
在幕后创建数组的事实,您可以简单地使用
fruitStream.filter(item->!Stream.of(“橙色”、“猕猴桃”、“甜瓜”、“苹果”、“西瓜”).anyMatch(item2->item2.equals(item))…
,但当然,基于
HashSet
的解决方案更有效。或者
Set otherFruits=Stream.of(“橙色”、“猕猴桃”、“甜瓜”、“苹果”、“西瓜”)。收集(Collectors.toSet());
更接近问题的代码。
banana
pear
public static void main(String[] args) {
    Stream<String> fruitStream = Stream.of("apple", "banana", "pear", "kiwi", "orange");
    Stream.of("orange", "kiwi", "melon", "apple", "watermelon")
            .map(Predicate::isEqual)
            .reduce(Predicate::or)
            .map(Predicate::negate)
            .map(fruitStream::filter)
            .orElse(fruitStream)
            .forEach(System.out::println);
}