Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/368.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.util.stream.stream#forEach 8中的代码> >代码> java .UTI.Struts。但为什么不呢?这不是链式函数。说它返回void而不是Streamit self_Java_Java 8 - Fatal编程技术网

为什么不链接java.util.stream.stream#forEach 8中的代码> >代码> java .UTI.Struts。但为什么不呢?这不是链式函数。说它返回void而不是Streamit self

为什么不链接java.util.stream.stream#forEach 8中的代码> >代码> java .UTI.Struts。但为什么不呢?这不是链式函数。说它返回void而不是Streamit self,java,java-8,Java,Java 8,像这样 Arrays .stream(Girls.toArray()) .forEach(Girls::getUp) .forEach(Girls::dressUp) .filter(/* Top 10 Girls */) .forEach(Gay.getMe()::gotGirl) .endFilter()// Not an API, but it means remove last filter .filter(/* Worst 10

像这样

Arrays
    .stream(Girls.toArray())
    .forEach(Girls::getUp)
    .forEach(Girls::dressUp)
    .filter(/* Top 10 Girls */)
    .forEach(Gay.getMe()::gotGirl)
    .endFilter()// Not an API, but it means remove last filter
    .filter(/* Worst 10 Girls */)
    .forEach(Gay.get(0)::gotGirl)


girls = Arrays
    .stream(Girls.toArray());
girls.forEach(g->{g.getUp();g.dressUp()});
girls.filter(/* Top 10 Girls */)
    .forEach(Gay.getMe()::gotGirl);
girls.filter(/* Worst 10 Girls */)
    .forEach(Gay.get(0)::gotGirl);
第一个比第二个好,但是第一个的性能更差


那么,为什么
forEach
是不可链接的呢?

您正在寻找的方法存在,并被调用和调用。使用
Stream::peek
,上述代码可能如下所示

Arrays
    .stream(Girls.toArray())
    .peek(Girls::getUp)
    .peek(Girls::dressUp)
    .filter(/* Top 10 Girls */)
    .peek(Gay.getMe()::gotGirl)
    ...

因为forEach是一个终端操作。它强制流使用其所有元素,并为每个元素调用使用者。一旦这样做了,流已经被消耗,并且不能被重用


一个流有您想要的任意多个中间操作,但只能有一个终端操作

forEach操作实际上是一个终端操作,因此不可链接,但可以将多个操作(在本例中为消费者)组合成一个
forEach
调用。例如:

    Consumer<String> c1 = s -> System.out.println(s + "1");
    Consumer<String> c2 = s -> System.out.println(s + "2");
    Consumer<String> c3 = s -> System.out.println(s + "3");
    Arrays.asList("a", "b", "c")
          .stream()
          .forEach(c1.andThen(c2).andThen(c3));
Consumer c1=s->System.out.println(s+“1”);
消费者c2=s->System.out.println(s+“2”);
消费者c3=s->System.out.println(s+“3”);
数组。asList(“a”、“b”、“c”)
.stream()
.forEach(c1.和第(c2).和第(c3));

不幸的是,如果没有一系列难看的转换,似乎不可能内联编写lambdas。

使用
链接,然后
确实是一种方法,但我们需要一些语法糖分来让它变得漂亮:

public class Consumers {
    public static <T> Consumer<T> of(Consumer<T> base) {
        return base;
    }
}
或(较短):

(由于forEach可直接在该系列中使用)

继续,可以内联写入lambdas,但只需强制转换第一个使用者:

Arrays.asList("a", "b", "c").forEach(
    ((Consumer<String>) s -> System.out.println(s + "1"))
    .andThen(s->System.out.println(s + "2"))
    .andThen(s -> System.out.println(s + "3"))
);
Arrays.asList(“a”、“b”、“c”).forEach(
((消费者)s->System.out.println(s+“1”))
.然后(s->System.out.println(s+“2”))
.然后(s->System.out.println(s+“3”))
);

As
,然后在Java8中将
定义为

default Consumer<T> andThen(Consumer<? super T> after) {
    Objects.requireNonNull(after);
    return (T t) -> { accept(t); after.accept(t); };
}

defaultconsumer,然后(consumerhowe,请注意,
peek()
map()
行为参数中可能干扰源或影响其他流操作结果的副作用是不允许的。
peek()
方法实际上只是用于调试/记录日志,而不是用于计算结果;类似地,
map()
应仅用于转换,而不是隐藏副作用。每次执行显式强制转换时,一个精灵就会死亡。
Arrays.asList("a", "b", "c").forEach(
    ((Consumer<String>) s -> System.out.println(s + "1"))
    .andThen(s->System.out.println(s + "2"))
    .andThen(s -> System.out.println(s + "3"))
);
default Consumer<T> andThen(Consumer<? super T> after) {
    Objects.requireNonNull(after);
    return (T t) -> { accept(t); after.accept(t); };
}
class CompositeConsumer<T> implements Consumer<T> {
    private final List<Consumer<T>> funcs;

    CompositeConsumer(List<Consumer<T>> funcs) {
        this.funcs = funcs;
    }

    @Override
    public void accept(T t) {
        for (Consumer<T> func: funcs) {
            func.accept(t); 
        } 
    }
}
List<Consumer<String>> funcs = ...
Arrays.asList("a", "b", "c")
      .forEach(new CompositeConsumer(funcs));