Java使用者介面

时间:2019-08-02 11:58:47

标签: java java-8 functional-programming

有人可以帮助我理解Java 8 Functional Interface中的以下代码 根据我的理解,accept()作为输入并处理它,但是在andThen()如何工作的情况下不返回任何值

  

accept()方法将类型T作为输入,但不返回任何值。

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

3 个答案:

答案 0 :(得分:1)

为了了解从该API获得return的好处,您可以尝试将实现可视化为:

default Consumer<T> andThen(Consumer<? super T> after) {
    Objects.requireNonNull(after);
    return new Consumer<T>() { // return the complete Consumer implementation
        @Override
        public void accept(T t) {
            Consumer.this.accept(t); // accept current consumer
            after.accept(t); // and then accept the 'after' one.
        }
    };
}

现在将其关联

(T t) -> { accept(t); after.accept(t); } 

是返回的Consumer,可确保首先对当前accept进行排序,然后再对after进行引用。

答案 1 :(得分:1)

功能接口只能具有一个抽象方法。但是,它可以具有任意数量的静态和默认方法。 Consumer的方法是:

  1. accept(T)

    • 这是Consumer的单一抽象方法。它接受类型为T的单个泛型参数,并且不返回任何内容(即void)。这是由lambda表达式或方法引用实现的方法。
  2. andThen(Consumer)

    • 这是默认方法。换句话说,它具有实现方式,因此是非抽象的。该方法接受一个Consumer并返回另一个Consumer。由于它是默认方法,因此Consumer的单个抽象方法仍为accept(T)

上面的内容解释了为什么Consumer可以有一个返回void以外的值的方法。现在,关于andThen的实现,重要的是要意识到实际上涉及到三个 Consumer

  1. 在其上调用andThen的实例。
  2. after引用的实例。
  3. 实例返回给调用者。

如果您设置代码格式,以免并非所有内容都在同一行上,那么可能会更容易遵循:

default Consumer<T> andThen(Consumer<? super T> after) {
    Objects.requireNonNull(after);
    // Returns Consumer instance #3. The lambda is the implementation
    // of the 'accept' method.
    return (T t) -> {
        accept(t);       // Invokes 'accept' on Consumer instance #1.
        after.accept(t); // Invokes 'accept' on Consumer instance #2.
    }
}

答案 2 :(得分:0)

我想我理解您的担心。您想知道如果andThen()返回void,为什么要在accept()之后调用accept()

问题是,首先定义一个Consumer对象,然后在该实例上 调用andThen()方法。例如:

Consumer<String> consumer = s -> System.out.println(s);
consumer.andThen(s -> System.out.println(s.toUpperCase()));