资讯专栏INFORMATION COLUMN

function包概述及大纲

garfileo / 2940人阅读

摘要:但这里为了解释上面的问题,彬哥还是得多啰嗦几句。这个方法谁能告诉我这是什么鬼彬哥现在也不知道,这还真不是彬哥故意卖关子。但是,方法的参数和返回值是需要我们关心和注意的。

大家有没有发现java.util.function包(本文后面简称function包)下的接口虽然比较多(目前共43个),但都是定义很简单的(方法很少),而我们理解起来却十分的困难。其实啊,这也不怪大家,是因为这个包下的接口并不是典型的Java的API,你可以说它们是“异类”。那么问题来了,典型的Java API是什么样子的呢?function包下的接口又“异”在哪里?

总所周知,Java是一种典型的OOP面向对象编程)语言,封装、继承、多态自不必多说,大家想必都十分清楚了。但这里为了解释上面的问题,彬哥还是得多啰嗦几句。面向对象一个很重要的标识就是,把结构和行为封装到一个类(对象)中。

典型的Java API就是这样子的,举个大家都很熟悉的例子:java.util.List。List是一个接口,是接口就只有方法,没有属性。但是,咱们来看看的List中的方法:size()、isEmpty()、contains(Object o)等等,按照正常人的思维,很容易、也很自然会将这些方法理解成:“假设我是个List的对象(实例)话,你们调用我的size()方法,我会将我的size告诉你;调用我的isEmpty()方法,我会告诉你我是不是空的;调用我的contains()方法,我会告诉你我是不是包含了你指定的这个对象”。大家有没有发现点什么?所有这些方法,很自然的加入到“我”这个语境(context)中去了。

那么再来看看这个咱们这个专题的主角function包看,找个典型代表出来:java.util.function.ConsumerConsumer是个Functional接口,有且只有一个“抽象方法”--void accept(T t)。这个accept方法谁能告诉我这™是什么鬼?彬哥现在也不知道,这还真不是彬哥故意卖关子。这是因为啊,你可以function包下的接口都是“无意义的”,这个“无意义”并不是说它们没有存在的意义,而是说它们都必须放到具体的语境中去才会真正的意义。或者说,它们是“非典型”的Java API就体现在,它们自己是没有语境(Context)的,它们实际上可以说就是为Lambda表达式而存在的--你不需要了解他叫什么(匿名的),它们是作为参数在对象的方法的中传递的。

它们没有自己的结构,只定义行为,这很不OOP,但很FP(Functional Programming),所以你可以说,从JDK 8开始,函数也可以被称作Java世界中的“第一公民”了。

来看个具体的例子,java.lang.IterableforEach方法:

default void forEach(Consumer action) {
    Objects.requireNonNull(action);
    for (T t : this) {
        action.accept(t);
    }
}

它的参数就是个Consumer,从forEach这个方法的定义来看,现在我们可以理解到“遍历我所包含的所有元素,对每个元素都执行一次action.accept()”,还有点抽象?不过已经有些好理解了是吧?咱们再进一步看:

List list = new ArrayList<>();
list.add("Hello ");
list.add("彬哥!");
list.forEach(s -> System.out.println(s)); // 这里当然也可以用更为简洁的方法引用来改写

现在在具体的语境里来理解就很容易了,“对于list中的每一个元素,执行我传进去的那个函数--Consumer”。可能咱们每天都在用类似的写法,但可能从来都没有意识到,那原来就是个Consumer啊。这不怪大家,因为“它们都是无意义的”,就像在这里,你根本不需要知道我们其实最后是调用的了Consumeraccept方法。
其实啊,所有java.util.function包下的接口的方法名,我们都不必关心,因为当我们用它们的时候,压根不会去显式地调用它们,方法名也是“无意义”的,它们只是方便大家去理解他的用途。但是,方法的参数和返回值是需要我们关心和注意的。

function包下总共有43个接口,嗯~看上去数量还是不少。不必害怕,其实满打满算也就这么5类:
FunctionSupplierConsumerPredicateOperator。这么看就很少了吧。这还不只,它们还有很多相似的地方,咱们再根据这些相似点分类、举一反三,就会简单很多。这里先按照这些共性的点,给这43个接口细分下归类:

Function类

一元:Function

原始类型

作为参数:DoubleFunctionIntFunctionLongFunction

作为返回值:ToDoubleFunctionToIntFunctionToLongFunction

相互转化:DoubleToIntFunctionDoubleToLongFunctionIntToDoubleFunctionIntToLongFunctionLongToDoubleFunctionLongToIntFunction

二元:BiFunction

原始类型

作为返回值:ToDoubleBiFunctionToIntBiFunctionToLongBiFunction

Supplier类

一元:Supplier

原始类型

作为返回值:BooleanSupplierDoubleSupplierIntSupplierLongSupplier

Consumer类

一元:Consumer

原始类型

作为参数:DoubleConsumerIntConsumerLongConsumer

二元:BiConsumer

原始类型

作为参数:ObjDoubleConsumerObjIntConsumerObjLongConsumer

Predicate类

一元:Predicate

原始类型

作为参数:DoublePredicateIntPredicateLongPredicate

二元:BiPredicate

Operator类

一元:UnaryOperator

原始类型

同时作为参数和返回值:DoubleUnaryOperatorIntUnaryOperatorLongUnaryOperator

二元:BinaryOperator

原始类型

同时作为参数和返回值:DoubleBinaryOperatorIntBinaryOperatorLongBinaryOperator

“额~彬哥,你这么把它们都列出来,搞得我更晕啦!”
别担心,对于它们每一类、每一个接口到底是什么?怎么用?咱们后面的章节都会一一具体说明。这个分类,一来,可以帮助大家先有个大体上的认识;二来,也可以作为后面章节的一个大纲,同时方便大家搞忘的时候来查阅。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/71743.html

相关文章

  • Function相关接口简介

    摘要:相关接口简介什么是接口,它代表这样的一个函数,接受一个参数,然后返回一个结果。参数和返回值相互转化的个作为参数的和个作为返回值的相互组合去掉重复的嗯,又到种接口,,,,,。 Function相关接口简介 什么是Function接口? interface Function,它代表这样的一个函数,接受一个参数,然后返回一个结果。 Function接口的functional方法 R app...

    gotham 评论0 收藏0
  • 史上最全 Android 中高级工程师面试复习大纲

    摘要:找工作之前看了很多面试题,复习资料,但是发现纯看面试题是不行的,因为靠背的东西是记不牢的,需要知识成体系才可以,所以笔者整理了一份复习大纲,基本涵盖了中高级工程师面试所必须知识点,希望可以通过此文帮助一些想换工作的朋友更好的复习,准备面试。 概述 都说金三银四青铜五,这几个月份是程序员最好的跳槽时间,笔者四月初也换了工作。找工作之前看了很多面试题,复习资料,但是发现纯看面试题是不行的,因为靠...

    chengjianhua 评论0 收藏0
  • 浅析微信支付:前篇大纲

    摘要:浅析微信支付前篇大纲本文是浅析微信支付系列文章的第一篇,主要会介绍一下为何写下这个系列以及对于微信支付的一点小经验,与君共勉。下面讲一下我是如何去学习微信支付的。 浅析微信支付:前篇大纲 本文是【浅析微信支付】系列文章的第一篇,主要会介绍一下为何写下这个系列以及对于微信支付的一点小经验,与君共勉。 以下会分几个步骤讲一下我学习微信支付的过程,也是一部辛酸史,也是希望朋友们不要再次跌进...

    mayaohua 评论0 收藏0

发表评论

0条评论

garfileo

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<