为什么java8流消费者andThen方法?

joh*_*ohn 4 java java-8 java-stream

我是 Java 8 的新手,只是想问一下下面两个代码片段在性能上有什么区别。

我知道这两种方法都有效,但我想知道为什么 Java 团队Consumer::andThen在我可以使用正常方法时创建了方法。

List<String> list = Arrays.asList("aaa","cccc","bbbb");
List<String> list2 = new ArrayList<>();
Run Code Online (Sandbox Code Playgroud)

//方法一

list.stream().forEach(x -> {
            list2.add(x);
            System.out.println(x);
        });
Run Code Online (Sandbox Code Playgroud)

//方法二

Consumer<String> c1 = s -> list2.add(s);
Consumer<String> c2 = s -> System.out.println(s);

list.stream().forEach(c1.andThen(c2));
Run Code Online (Sandbox Code Playgroud)

IMO,方法 1更好,为什么又是方法 2?如果两者相同,那么为什么要创建andThen()方法?我想一定有他们创造的原因。

换句话说,该andThen()方法究竟何时真正有用?

Era*_*ran 12

我同意Consumer<String>为每个语句创建一个单独的实例只是为了使用andThen.

但是,如果您已经有两个Consumer<String>实例(c1c2),并且需要同时执行这两个实例,则可以编写:

list.forEach(x -> {
        c1.accept(x);
        c2.accept(x);
    });
Run Code Online (Sandbox Code Playgroud)

或者

list.forEach(c1.andThen(c2));
Run Code Online (Sandbox Code Playgroud)

在这种情况下,后者显然更干净。

编辑:

我想在您创建自己的Consumers(即不重新使用预先存在的)时扩展这种情况。将 lambda 表达式分配给Consumer变量时,您可以Consumer在多个位置使用该实例,而不是复制 lambda 表达式。对于任何功能接口都是如此。

一旦您决定使用一个Consumer变量,决定是使用单个Consumer实现复杂逻辑还是 2 个更简单的Consumers,每个实现逻辑的一部分,取决于是否需要能够在某些情况下只执行部分逻辑案例(或更改部分逻辑的执行顺序)。

拥有c1c2允许您选择以下任一选项:

list.forEach(c1);
list.forEach(c2);
list.forEach(c1.andThen(c2));
list.forEach(c2.andThen(c1));
Run Code Online (Sandbox Code Playgroud)

如果您有一个消费者同时执行c1and的逻辑c2,则灵活性会降低。

  • @MushifAliNawaz 这是真的 (2认同)
  • @john `List` 已经有一个 `forEach()` 方法,所以不需要创建一个 `Stream` 。 (2认同)
  • @john在你的简单示例中,仅仅为了使用“andThen”而预定义两个“Consumer”是没有意义的,所以是的,我会避免使用它。 (2认同)
  • @约翰,这取决于。在我看来,带大括号的 lambda 表达式使代码不太整洁。如果您有一个具有复杂逻辑(许多语句)的“Consumer”,您应该考虑将该逻辑放入方法中,并使用方法引用。如果“Consumer”有理由单独存在,则拆分“Consumer”是有意义的 - 例如,如果在某些情况下您仅使用“c1”,在其他情况下您仅使用“c2”,有时您将两者结合起来。 (2认同)