JDK8函数式编程(一)

343 阅读2分钟

简介

image.png

编程特性

  • 不可变
    • 好处:
      • 不需要考虑并发的问题
      • 把对象的状态变化拆解开来,大大减少了出现BUG的可能性
  • 惰性求值
  • 闭包
  • 高阶函数
    • 传入一个函数然后返回一个函数
  • 柯里化
  • 部分应用
  • 结合率

适用场景

  • 创建线程
  • 策略模式,如comparator
  • UI 编程
  • 异步回调
  • ...

Lambda表达式

image.png

使用lambda表达式的一般语法是

(Parameters) -> { Body }

-> 分隔参数和lambda表达式主体。

参数括在括号中,与方法相同,而lambda表达式主体是用大括号括起来的代码块。

注意

  • lambda表达式主体可以有局部变量,语句。我们可以在lambda表达式主体中使用break,continue和return。我们甚至可以从lambda表达式主体中抛出异常。

  • lambda表达式没有名称,因为它表示匿名内部类。

  • lambda表达式的返回类型由编译器推断。

  • lambda表达式不能像方法一样有throws子句。

  • lambda表达式不能是泛型,而泛型在函数接口中定义。

隐式lambda表达式

未声明其参数类型的lambda表达式称为隐式lambda表达式。

语法糖

image.png

函数式接口

image.png

lambda表达式表示函数式接口的实例。

lambda表达式的类型是一个函数式接口类型。

Java中万物皆对象,所以lambda表达式实际是创建了一个函数式接口的对象。

注意

  • lambda表达式本身不能用作独立的表达式。
  • lambda表达式的类型由编译器推断。
  • 我们不能使用以下类型的方法来声明一个函数式接口:
    • 默认方法
    • 静态方法
    • 从Object类继承的方法
      • 例如:java.util.Comparator接口中有两个抽象方法: compare() equals()equals()方法是Object类中的 equals()方法的重新声明。

内置常用函数式接口

输入返回值class
TRFunction< T, R >
voidTSupplier< T >
TvoidConsumer< T >
voidvoidRunnable
TBooleanPredicate< T >
TTUnaryOperator< T >

方法引用

image.png

image.png

这种方法引用方式有些难理解,如上图所示,接口FN中的apply方法接收的参数是arg1...argN,其中arg1的类型为T,T类型中有个方法tMethod,它接收的参数是arg2...argN,当我们需要一个FN接口时,正常的调用是(arg1...argN) -> {},还可以传比FN接口方法少一个参数的方法(只能少一个参数,且少的参数必须是第一个,并且这个少参方法的类型必须是FN接口中apply方法的第一个参数的类型,在上图中即是T), 上图中 T 的tMethod方法 即可以传递给接口FN,当调用FN中的apply方法时,第一个参数arg1作为实例T, 剩下的arg2...argN作为参数传给tMethod。

代码示例

github地址