Java面向对象之函数式编程

函数式编程

在数学中,函数就是有输入量、输出量的一套计算方案,也就是“拿什么东西做什么事情”。相对而言,面向对象过分强调“必须通过对象的形式来做事情”,而函数式思想则尽量忽略面向对象的复杂语法——强调做什么,而不是以什么形式做。

做什么,而不是怎么做

new Thread(new Runable(){
    @Override
    public void run(){
       // TODO Auto-generated method stub 
    }
}).start()

我们真的希望创建一个匿名内部类对象吗?

不!我们只是为了做这件事情而不得不创建一个对象。

函数式编程

函数式编程的本质:传递一段代码

使用JDK 8中新增的Lambda表达式,这种表达式只针对有一个抽象方法的接口实现,以简洁的表达式形式实现接口功能来作为方法参数

new Thread(
    ()-> System.out.println("多线程任务执行:")
).start();

这段代码和刚才的执行效果是完全一样的,可以在1.8或更高的编译级别下通过。从代码的语义中可以看出:我们启动了一个线程,而线程任务的内容以一种更加简洁的形式被指定

Lambda表达式

Lambda表达式基本语法格式

image20210825100724053.png

简化

Lambda表达式的省略写法

  1. 如果Lambda表达式的方法体代码只有一行代码,可以省略大括号不写,同时要省略分号!

  2. 如果Lambda表达式的方法体代码只有一行代码,可以省略大括号不写。

    此时,如果这行代码是return语句,必须省略return不写,同时也必须省略“;”不写

  3. 参数类型可以省略不写

  4. 如果只有一个参数,参数类型可以省略,同时()也可以省略

方法引用

说明:Lambda表达式的主体只有一条语句时,程序不仅可以省略包含主体的花括号,还可以通过英文双冒号::的语法格式来引用方法和构造器(即构造方法)

作用:可以进一步简化Lambda表达式的书写,其本质都是对Lambda表达式的主体部分已存在的方法进行直接引用,主要区别就是对普通方法与构造方法的引用而已

  1. 类名应用静态方法

    定义:类名引用静态方法也就是通过类名对静态方法的引用,该类可以是Java自带的特殊类,也可以是自定义的普通类

    // 使用Lambda表达式方式
    printAbs(-10,n->Math.abs(n));
    // 使用方法引用的方式
    printAbs(-10,Math::abs);
    
  2. 对象名引用方法

    定义:对象名引用方法指的是通过实例化对象的名称来对其方法进行的引用

    // 使用Lambda表达式方式
    printUpper("Hello",t->stu.printUpperCase(t));
    // 使用方法引用的方式
    printUpper("Hello",stu::printUpperCase);
    
  3. 构造器引用方法

    定义:构造器引用指的是对类自带的构造器的引用

    // 使用Lambda表达式方式
    printName("张三",name->new Person(name));
    // 使用构造器引用的方式
    printName("张三",Person::new);
    
  4. 类名引用普通方法

    定义:类名引用普通方法指的是通过一个普通类的类名来对其普通方法进行的引用

    // 使用Lambda表达式方式
    printUpper(new StringUtils(),"Hello",(object,t)->object.printUpperCase(t));
    // 使用方法引用的方式
    printUpper(new StringUtils(),"Hello",StringUtils::printUpperCase);
    

函数式接口

接口中有且只有一个抽象方法时才能使用Lamdba表达式代替匿名内部类。这是因为Lamdba表达式是基于函数式接口实现的。

所谓函数式接口是指有且仅有一个抽象方法的接口,Lambda表达式就是Java中函数式编程的体现,只有确保接口中有且仅有一个抽象方法,Lambda表达式才能顺利地推导出所实现的这个接口中的方法。

定义:在JDK 8 中,接口上标注有@FuncitonalInterface注解的即为函数式接口,在函数式接口内部有且只有一个抽象方法。

说明:@FunctionalInterface注解只是显示的标注了接口是一个函数式接口,并强制编辑器进行更严格的检查,确保该接口是函数式接口。

Q.E.D.