1

【JAVA8】快速理解Consumer、Supplier、Predicate与Function

 1 year ago
source link: https://blog.csdn.net/qq_33591903/article/details/102948344
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

                          快速理解Consumer、Supplier、Predicate与Function

这几个接口都处在java.util.function包下,Consumer(消费型),Supplier(供给型)、Predicate(判断型)与Function(转换型),暂时不理解他们的类型没关系。

如果对Lambda不怎么理解的同学,可以先移步到我的另外一篇文章对Lambda的理解


二、Consumer

Consumer是一个消费型的接口,它接收一个🍉,然后对这个西瓜进行消费,连西瓜籽都不带留下的。

先看Consumer接口的源码,有一个未实现的抽象方法,和一个默认方法(jdk1.8之后,接口里面可以有默认方法和静态方法)。

我们只在意这个accept方法,接收一个泛型参数,不返回任何值。ok,我们来简单实现它

好了,用脚指头想着,肯定是输出1了。

接下来我们使用lambda表达式来对此匿名内部类进行改写。此时该lambda的类型就是Consumer类型。

    consumer=i-> System.out.println(i);

当然我们也可以使用方法引用

    consumer=System.out::println;

在Stream类中,我们发现常用的forEach接口接收一个Consumer类型的参数,源码如下

    void forEach(Consumer<? super T> action);

二话不说,我们将consumer传入forEach中,来实现遍历集合的操作。

将中间consumer对象去掉呢,代码会变得更加简洁。咦,到这里,是不是有一种似曾相识的感觉,原来是这样演变来的。

Consumer总结:

  • Consumer接口是一个消费型的接口,只要实现它的accept方法,就能作为消费者来输出信息。
  • lambda、方法引用都可以是一个Consumer类型,因此他们可以作为forEach的参数,用来协助Stream输出信息。
  • Consumer还有很多变种,例如IntConsumer、DoubleConsumer与LongConsumer等,归根结底,这些变种其实只是指定了Consumer中的泛型而已,方法上并无变化。

三、Supplier

Supplier是一个供给型的接口,我们可以无条件的从它这里获取东西。

我们不需要为get方法传入任何参数,就能获得一个结果,这不是白嫖吗?那我想要一个随机数

下一步,Supplier可以哪些地方呢,毕竟是可以白嫖的,谁不喜欢呢?我们看看Supplier在Optional中的应用。

该方法接收Supplier类型的参数,当Optional内部的value不为空时,才会返回Supplier中的值。例如

这必定返回Supplier中的随机值,因为Optional.empty()包含的值就是null。

Supplier总结:

  • Supplier是一个供给型的接口,其中的get方法用于返回一个值。
  • Supplier也有很多的变种,例如IntSupplier、LongSupplier与BooleanSupplier等

四、Predicate

Predicate是一个判断型接口,看看它的源码。

该接口将jdk1.8中接口的变化体现的淋漓尽致,接口不再“纯粹”了,可以有默认方法与静态方法了,下次面试再问道,就得分情况喽,哭出声。

要理解一个接口,我们就去实现它的方法。

很明显,输出是false。等等,既然可以进行判断,那和Stream.filter()有没有关系呢?

    Stream<T> filter(Predicate<? super T> predicate);

果然是有关系的,啧啧啧,我这敏锐的嗅觉。那我们把Predicate对象传入filter试试?

很简单,输出是678。

Predicate总结:

  • Predicate是一个判断型的接口,用一个test方法去测试传入的参数。
  • 当然,Predicate也有对应的变种。

五、Function

Function是一个功能型的接口,用于将一种类型的数据转化为另外一种类型的数据。

重点关注它的apply方法,现在就去实现它,并将之传入进Stream.map()方法中试试。

输出12,可以看得出,Function中的apply方法将Student类型的数据转化为对应id的Integer类型的数据。

Function总结:

  • Function是一个转换型的接口,其中的apply可以将一种类型的数据转化成另外一种类型的数据。
  • Function的变种就更多了。

首先只要记住这四个接口的类型,Consumer(消费型)、Supplier(供给型)、Predicate(判断型)与Function(转换型),

再记住他们对应的抽象方法Consumer(accpet)、Supplier(get)、Predicate(test)与Function(apply)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK