Java.util.function
包中轻松找到 。不过Java最多只准备了具有两个参数的函数式接口 , 但是接口又不难写 , 只要我们理解了函数式接口的意义和用法 , 自己写一个能容纳更多参数的函数式接口不过是信手拈来罢了 。
// 举个例子 , 一个有四个泛型参数的函数式接口@FunctionalInterfacepublic interface TriFunction<T, U, V, R>{R apply(T t, U u, V v, R r);}
补充
在Java给出的函数式接口中 , 我们只能看到一部分涉及基本类型的函数式接口 。其余都是由泛型完成的 , 为什么要这么做呢?估计就是因为对于某些很常用的函数式接口 , 如整形输入+Double输出这样 。如果我们采用泛型Function<Integer, Double>
来实现 , 就涉及到自动装箱和自动拆箱的性能问题 , 如果该方法会被大量调用 , 那么还是直接声明清楚其中的类型对于我们的整体性能更为有利
2、Lambda表达式lambda表达式本质上是一个匿名方法 , 其中以->
为分隔符 , 在其前的是输入参数 , 在其后的是返回变量 。
lambda表达式是函数式接口的其中一个"成果"——另一个是方法引用 , 我们可以将相同输入输出参数 (类型和数量都匹配) 的lambda表达式赋给一个函数式接口 , 通过调用赋值后的接口再来调用我们创建的lambda表达式 。
lambda表达式的语法如下所示:
- 参数
->
, 它可以读作产生(produces)- 方法体
msg -> msg + "!";msg -> msg.upperCase();() -> "hello world";h -> {System.out.println(h + "abcdefg");return h.lowerCase();}
有以下这些问题需要注意:- lambda表达式如果只有一个参数 , 可以只写该参数不写括号 , 但你要知道这是一种特殊情况而不是相反
- 通常需要括号将参数包裹起来 , 为了一致性考虑 , 单个参数时也可以使用括号
- 没有参数时 , 必须要有括号指代输入的参数
- 存在多个参数时必须要以括号包裹 , 逗号分割
- 如果一句话就可以表示返回值 , 那么就直接写到方法体所在的位置 , 此时
return
关键字是不合法的 - 如果一句话无法囊括 , 那么就需要使用花括号将所有函数体包裹并以
return
返回结果
注意 , 如果你要利用lambda表达式实现递归调用自身的话 , 必须要将该表达式赋值给一个静态变量或一个实例变量 , 否则该语句对于编译器可能过于复杂 , 会产生编译错误 。
3、方法引用方法引用指向的是方法 , 通过类名或对象名 , 跟
::
, 然后跟方法名就可以实现方法引用 , 注意 , 这种方法并不需要在方法名后面加上参数列表 。className::method; // 注意 , 没有括号!
我们可以通过一个接口 , 引用那些签名 (方法的参数类型数量以及返回类型) 一致的方法 。需要注意的是 , 任何方法要被引用 , 都需要该方法存在其绑定对象 , 这个对象对于静态方法而言就是其Class对象 , 而对于普通方法而言 , 则需要确保存在该类对象 。
该对象要么被你创建出来并显式的赋给方法引用 , 类似这样
经验总结扩展阅读
- 不妨试试更快更小更灵活Java开发框架Solon
- 11 微服务架构学习与思考:开源 API 网关02-以 Java 为基础的 API 网关详细介绍
- java 新特性之 Stream API
- java 入土--集合详解
- 4 Java I/O:AIO和NIO中的Selector
- Vue3 SFC 和 TSX 方式调用子组件中的函数
- C++ 函数重载解析策略
- 3 Java I/O:NIO中的Buffer
- 火漆可以用来干嘛
- Java程序员必会Synchronized底层原理剖析