Java函数式编程:一、函数式接口,lambda表达式和方法引用( 二 )

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表达式的可读性极佳 , 所以如果你需要使用这样的方法 , 你应该掌握lambda表达式 。
注意 , 如果你要利用lambda表达式实现递归调用自身的话 , 必须要将该表达式赋值给一个静态变量或一个实例变量 , 否则该语句对于编译器可能过于复杂 , 会产生编译错误 。
3、方法引用方法引用指向的是方法 , 通过类名或对象名 , 跟:: , 然后跟方法名就可以实现方法引用 , 注意 , 这种方法并不需要在方法名后面加上参数列表 。
className::method; // 注意 , 没有括号!我们可以通过一个接口 , 引用那些签名 (方法的参数类型数量以及返回类型) 一致的方法 。
需要注意的是 , 任何方法要被引用 , 都需要该方法存在其绑定对象 , 这个对象对于静态方法而言就是其Class对象 , 而对于普通方法而言 , 则需要确保存在该类对象 。
该对象要么被你创建出来并显式的赋给方法引用 , 类似这样

经验总结扩展阅读