欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Lambda表达式详解(java8新特性,函数式编程)

程序员文章站 2022-03-11 10:13:40
Lambda表达式作为Java8的一个重要性能,那么它到底是做什么的呢?阅读本文能让你明白什么叫Lambda,用它你能做什么,以及所谓的函数式接口又到底是什么东西等((java8新特性,@FunctionalInterface,::关键字))...

在JDK1.8中引入了一个重要的新特性:Lambda表达式。

Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。

使用 Lambda 表达式可以使代码变的更加简洁紧凑,在学习Lambda表达式前我们先来思考一下为什么会出现它。

1.为什么会出现Lambda表达式

首先我们思考下在java中如何表示一个值?很简单,定义一个变量,然后赋值
Lambda表达式详解(java8新特性,函数式编程)

那么如何表示一段代码块的执行逻辑呢?也很简单,定义一个函数,函数方法体写上对应的执行逻辑
Lambda表达式详解(java8新特性,函数式编程)

可如果我想把这个函数赋予某个变量(aBlockOfCode)并当做入参传递呢?

比如说如此:

Lambda表达式详解(java8新特性,函数式编程)

在Java 8之前,这么做是不合法的。但是Java 8问世之后,利用Lambda特性,就可以做到了,并且Lambda的设计者还很贴心的帮我们简化了这一定义:

Lambda表达式详解(java8新特性,函数式编程)

可以看到,我们非常优雅的把“一块代码”赋给了一个变量。而“这块代码”,或者说“这个被赋给一个变量的函数”,就是一个Lambda表达式

而这个变量的类型是什么呢?

Java8中,定义了一种新的接口类型: 函数式接口,一个接口函数需要被实现的接口类型,我们叫它”函数式接口“ ,并且还为这个接口定义了一个专属声明 @FunctionalInterface ,在接口上加上该声明代表该接口内只有一个函数需要被实现

Lambda表达式详解(java8新特性,函数式编程)

其实我们发现,上述表达式其实通过定义一个借口的实现类,然后实例化也能达到同样的目的,但是代码量上却多了很多。

Lambda表达式详解(java8新特性,函数式编程)

这也是Lambda表达式的最直观的作用: 使得代码变得异常简洁。

而且Lambda结合Java8的众多新特性:FunctionalInterface Lib, forEach, stream(),method reference等你会看到这一优势会被无限放大!

2.Lambda表达式的基础语法

Lambda 表达式的2种语法格式如下:

  1. (parameters) -> expression
  2. (parameters) -> {statements;}

以下是lambda表达式的重要特征:

1.可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。

2.可选的参数圆括号:一个参数无需定义圆括号,但0或多个参数需要定义圆括号。

3.可选的大括号: 如果表达式只有一行,那么表达式两边的花括号可以省略 。

4.可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。

Lambda 表达式的简单例子

  • 1.多参数的情况

    (1). lambda表达式的基本格式为(x1,x2)->{表达式…};

    (2).在上式中,lambda表达式带有两个参数,此时参数类型可以省略,但两边的括号不能省

    (3)…如果表达式只有一行,那么表达式两边的花括号可以省略

    //接受2个带参参数,并返回他们的差值 
    (int x, String y) -> String.valueOf(x) + y  
    
    // 4. 接收2无参参数,返回他们的和  
    (x, y) -> x – y  
    
    
  • 2.无参数的情况

    参数的括号不能省略, 其他语法同多参数

//创建并启动一个线程
new Thread(()-> System.out.println("hello, i am thread!")).start();
  • 3.一个参数的情况

    可以省略参数的括号和类型, 其他语法同多参数

//  接收一个参数,可以省略参数的括号和类型
x -> 2 * x  
 
// 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)  
(String s) -> System.out.print(s)

3.Java8中提供的常用函数式接口

前面我们说了,为了配合Lambda表达式的使用,Java8中定义了一种新的接口类型: 函数式接口,即一个接口函数需要被实现的接口类型,由 @FunctionalInterface 声明。其实Java为了方便我们的使用,还提供了很多常用函数式接口。

利用函数式接口包:java.util.function

Lambda表达式详解(java8新特性,函数式编程)

常见的有

Function:提供任意一种类型的参数,返回另外一个任意类型返回值。 R apply(T t);

Consumer:提供任意一种类型的参数,返回空值。 void accept(T t);

Supplier:参数为空,得到任意一种类型的返回值。T get();

Predicate:提供任意一种类型的参数,返回boolean返回值。boolean test(T t);

Lambda表达式详解(java8新特性,函数式编程)

4.方法引用

Java 8 中还新增了一个关键字“ :: ”我们可以通过 " :: " 关键字来访问类的构造方法,对象方法,静态方法

演示如下:

1.先自定义一个类

class Demo {
    //无参构造
    Demo() {}
    //有参构造
    Demo(String something) {
        System.out.println(something);
    }
    //多参构造
    Demo(String something,Integer num) {
        System.out.println(something+num);
    }

    //静态方法
    static String startsMethod(String s) {
        return String.valueOf(s.charAt(0));
    }

    //
    String methodOne(String s) {
        return String.valueOf(s.charAt(s.length()-1));
    }

    void methodTwo() {
        System.out.println();
    }
}

2.先定义一个函数式接口

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tEDdjg5i-1606478057603)(Lambda表达式详解,java8新特性.assets/1606463685803.png)]

接口 IConvert, 传参为类型 F,返回类型 T。

接下来让我们演示通过 ::关键字来进行方法访问。

  1. 访问静态方法

     IConvert<String,String> ic1 =  Demo::startsMethod;
    ic1.convert("静态方法访问");
    
  2. 访问对象方法

     IConvert<String,String> ic2 =  new Demo()::methodOne;
     ic2.convert("对象方法访问");
    
  3. 访问构造方法

    IConvert<String,Demo> ic3 =  Demo::new;
    ic3.convert("构造方法访问");
    

我们可以这样认为,将接口IConvert<F,T>当做一个定义好的模板, Demo类中的各个方法当做这个模板的实现,只要Demo中的方法符合 IConvert接口的入参与出参定义,就可以直接将方法赋予模板。

引用于参考:
https://www.zhihu.com/question/20125256/answer/324121308

本文地址:https://blog.csdn.net/weixin_43828467/article/details/110244897