Java 8 函数式编程(二)(Consumer 接口)

542 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情

上一篇文章我们讲的是Java 8 函数式接口的理解及语法。这篇文章开始我们介绍Java 8 中几个预先定义的函数式接口及其经常使用的类进行介绍,首先介绍Consumer接口。

Java 8 预定义的函数式接口

Consumer 接口

上一篇文章中我们拿Consumer 举例,大概介绍了函数式接口的语法及理解,这里我们再仔细地介绍一下Consumer 接口。

首先我们可以确定的是,Consumer是一个函数式编程接口。

通过这个方法名我们可以知道,Consumer的意思就是消费,我们可以这么记忆:即针对某个东西我们来使用、消费它,进入之后就出不来了,因此它内部的接口名称就是accept,代表“无偿接收“;也就是说,有Consumer 中的接口accept 是个有输入而无输出的方法。

Comsumer 接口中,除accept方法之外,它还包含有andThen这个方法,但是只看andThen方法定义可能不是太好理解,我们来看Consumer接口的全部定义:

@FunctionalInterface
public interface Consumer<T> {

    /**
     * Performs(演出、表演、执行、履行、运行) this operation on the given argument.
     *
     * @param t the input argument
     */
    void accept(T t);

    /**
     * Returns a composed {@code Consumer} that performs, in sequence, this
     * operation followed by the {@code after} operation. If performing either
     * operation throws an exception, it is relayed to the caller of the
     * composed operation.  If performing this operation throws an exception,
     * the {@code after} operation will not be performed.
     *
     * @param after the operation to perform after this operation
     * @return a composed {@code Consumer} that performs in sequence this
     * operation followed by the {@code after} operation
     * @throws NullPointerException if {@code after} is null
     */
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

我们来分析一下andThen 的代码。

方法在调用的过程中,需要传入一个Consumer 类型的参数after,参数不能为null

然后进入函数体,函数体内首先调用的是accept方法,然后调用传入的after参数的accept方法。

通过这个方法定义,我们可以得出结论:andThen这个方法就是在调用当前Consumer中的方法后还要调用其它的Consumer中的方法。

使用示例:

public static void main(String[] args) {
  Consumer f = n -> {
    System.out.println("========");
    System.out.println(n + "f1");
    System.out.println("++++++++");
  };
  Consumer f2 = n -> {
    System.out.println("++++++++");
    System.out.println(n + "f2");
    System.out.println("--------");
  };
  f.andThen(f2).accept(7);
}

对于Consumer 接口中的andThen 方法来说,有的人可能不理解,明明没有看到任何关于Consumer 的东西,为什么会“返回”一个Consumer?

其实我们可以观察andThen 方法中的代码,它其实是一个典型的Consumer 接口中accept 方法的结构,而我们参考上面声明一个Consumer 实例的代码,即:

Consumer consumer = n -> System.out::println;

可以知道,等号右边代表的就是一个Consumer 接口实例。所以我们将其返回,也自然andThen 方法返回的就是Consumer 接口实例了。

总结

Consumer 接口的使用也比较清晰明了,在日常使用中可以完成很多功能,比如说为对象赋值,输出结果,抛出异常等。我们要做到活学活用。

如果不理解andThen 方法也没有关系,暂时先记住使用的方法,在后续越用越多,就会自然而然地理解了。

后面的文章我们及时性解药Java 中其他自定义并常使用到函数接口。