function包概述及大纲

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

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

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

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

它们没有本身的结构,只定义行为,这很不OOP,但很FP(Functional Programming),因此你能够说,从JDK 8开始,函数也能够被称做Java世界中的“第一公民”了。this

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

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

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

List<String> 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类io

    • 一元:Function

      • 原始类型

        • 做为参数:DoubleFunctionIntFunctionLongFunction
        • 做为返回值:ToDoubleFunctionToIntFunctionToLongFunction
        • 相互转化:DoubleToIntFunctionDoubleToLongFunctionIntToDoubleFunctionIntToLongFunctionLongToDoubleFunctionLongToIntFunction
    • 二元:BiFunction

      • 原始类型

        • 做为返回值:ToDoubleBiFunctionToIntBiFunctionToLongBiFunction
  • Supplier类

    • 一元:Supplier

      • 原始类型

        • 做为返回值:BooleanSupplierDoubleSupplierIntSupplierLongSupplier
  • Consumer类

    • 一元:Consumer

      • 原始类型

        • 做为参数:DoubleConsumerIntConsumerLongConsumer
    • 二元:BiConsumer

      • 原始类型

        • 做为参数:ObjDoubleConsumerObjIntConsumerObjLongConsumer
  • Predicate类

    • 一元:Predicate

      • 原始类型

        • 做为参数:DoublePredicateIntPredicateLongPredicate
    • 二元:BiPredicate
  • Operator类

    • 一元:UnaryOperator

      • 原始类型

        • 同时做为参数和返回值:DoubleUnaryOperatorIntUnaryOperatorLongUnaryOperator
    • 二元:BinaryOperator

      • 原始类型

        • 同时做为参数和返回值:DoubleBinaryOperatorIntBinaryOperatorLongBinaryOperator

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

相关文章
相关标签/搜索