你们有没有发现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.Iterable
的forEach
方法: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
啊。这不怪你们,由于“它们都是无心义的”,就像在这里,你根本不须要知道咱们其实最后是调用的了Consumer
的accept
方法。
其实啊,全部java.util.function包下的接口的方法名,咱们都没必要关心,由于当咱们用它们的时候,压根不会去显式地调用它们,方法名也是“无心义”的,它们只是方便你们去理解他的用途。可是,方法的参数和返回值是须要咱们关心和注意的。继承
function
包下总共有43个接口,嗯~看上去数量仍是很多。没必要惧怕,其实满打满算也就这么5类:Function
、Supplier
、Consumer
、Predicate
、Operator
。这么看就不多了吧。这还不仅,它们还有不少类似的地方,我们再根据这些类似点分类、触类旁通,就会简单不少。这里先按照这些共性的点,给这43个接口细分下归类:接口
Function类io
一元:Function
原始类型
DoubleFunction
,IntFunction
,LongFunction
ToDoubleFunction
,ToIntFunction
,ToLongFunction
DoubleToIntFunction
,DoubleToLongFunction
,IntToDoubleFunction
,IntToLongFunction
,LongToDoubleFunction
,LongToIntFunction
二元:BiFunction
原始类型
ToDoubleBiFunction
,ToIntBiFunction
,ToLongBiFunction
Supplier类
一元:Supplier
原始类型
BooleanSupplier
,DoubleSupplier
,IntSupplier
,LongSupplier
Consumer类
一元:Consumer
原始类型
DoubleConsumer
,IntConsumer
,LongConsumer
二元:BiConsumer
原始类型
ObjDoubleConsumer
,ObjIntConsumer
,ObjLongConsumer
Predicate类
一元:Predicate
原始类型
DoublePredicate
,IntPredicate
,LongPredicate
BiPredicate
Operator类
一元:UnaryOperator
原始类型
DoubleUnaryOperator
,IntUnaryOperator
, LongUnaryOperator
二元:BinaryOperator
原始类型
DoubleBinaryOperator
,IntBinaryOperator
,LongBinaryOperator
“额~彬哥,你这么把它们都列出来,搞得我更晕啦!”别担忧,对于它们每一类、每个接口究竟是什么?怎么用?我们后面的章节都会一一具体说明。这个分类,一来,能够帮助你们先有个大致上的认识;二来,也能够做为后面章节的一个大纲,同时方便你们搞忘的时候来查阅。