ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java8之lambda表达式

2020-07-14 19:32:22  阅读:248  来源: 互联网

标签:String int void 接口 Java8 public 表达式 lambda


简介

Lambda 表达式是 Java 1.8 跟 Stream 机制一同推出的。Lambda 表达式极大地减少了代码量,增加了代码的可读性。
引入 Lambda 表达式之后,Java 开始支持把函数作为参数传递

前置条件

使用 Lambda 表达式的前置条件,作为参数的接口必须是函数式接口

  1. 首先类型必须是接口 interface,不能是类 class。比如,抽象类就不可以。
  2. 函数式接口有且仅有一个未被覆写的抽象方法

举例:

  • Object 中方法不算
// MyRunnable 仍然算是一个“函数式接口”
public interface MyRunnable extends Runnable {
    String toString();
    boolean equals(Object obj);
    int hashCode();
}
  • 接口中的 default 方法不算
// MyRunnable2 仍然算是一个“函数式接口”
public interface MyRunnable2 extends Runnable {
    default void run2() {}
}

FunctionalInterface 注解

@FunctionalInterface 可以帮助我们在编译期识别出一个接口是否是“函数式接口”:

Not Functional Interface

参数的传递

假如我们有一个如下含义的“函数式接口”:

@FunctionalInterface
public interface Formatter {
    void format(String name, int age);
}

我们可以构造一个测试:

public class LambdaTest {

    public static void main(String[] args) {
        print((String name, int age)-> System.out.println(String.format("name:%s age:%d", name, age)), "ziyu", 18);
    }

    public static void print(Formatter formatter, String name, int age) {
        formatter.format(name, age);
    }
}

多个参数

当有多个参数时,可以选择省略所有参数类型声明:
lambda-params
注意:
不能省略一部分保留一部分。(String name, age) -> System.out.println(name); 这是不合法的!

单个参数

lambda-param
当只有一个参数时,除了可以省略参数类型,还可以进一步省略掉括号。

编写方式

没有返回值

Runnable 就是一个常用的“函数式接口”,它的抽象方法 run() “没有返回值”, 刚好适合用于此处的演示。测试例子如下:

public class LambdaTest2 {
    public static void main(String[] args) {
        runIt(()->{
            System.out.println("123");
        });
    }

    static void runIt(Runnable runnable) {
        new Thread(runnable).start();
    }
}

return-void

  • 如果写成多行表达式,那么需要 {} 来表示代码块,且每一行代码结束时需要书写 ; 表示语句的结束。
  • 如果代码块中只有一条语句,那么可以通过省略 {}; 来简写为单行表达式

有返回值

我们定义一个 IdFactory 接口来做演示:

public interface IdFactory {
    String generateId();
}

我们的示例代码如下:

import java.util.UUID;

public class LambdaTest3 {

    public static void main(String[] args) {
        String name = getId(()-> UUID.randomUUID() + "");
        System.out.println(name);
    }

    static String getId(IdFactory factory) {
        return factory.generateId();
    }

}

return-string

  • 如果写成多行表达式,除了需要 {} 来表示代码块,和每一行代码结束时需要书写 ; 表示语句的结束以外,还应该在需要返回值的方法用 return 来返回值。
  • 如果代码块中只有一条语句,那么可以通过省略 {}; 以及 return 来简写为单行表达式

方法引用

比如我们要写一段代码,用来打印出完整的加法表达式 a + b = c,并且要求根据 a 和 b 求出 c 作为函数返回值。
首先我们定一个“计算器”接口:

public interface Calculator {
    int compute(int a, int b);
}

接着我们写一个测试用例:

public class LambdaTest3 {

    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        // 这里不能用 (a, b), 那样的话会产生歧义,使得编译器报错
        runIt((x, y)->{
            System.out.print(x);
            System.out.print(" + ");
            System.out.print(y);
            System.out.print(" = ");
            System.out.println(x + y);
            return x + y;
        }, a, b);
    }

    static void runIt(Calculator calculator, int a, int b) {
        calculator.compute(a, b);
    }
}

静态方法引用

static-method-reference

  • 在 LambdaTest2 中定一个静态方法 sum
  • 使用静态方法引用 LambdaTest2::sum
  • 这样在运行静态方法 runIt 中的第一行 calculator.compute(a, b) 时,ab 会通过静态方法引用传递给静态方法 sum

通过这种方式,即简化了参数的传递,也把“多行表达式”简化为了“单行表达式”

成员方法引用

member-method-reference

  • new LambdaTest2()::sum: 先新建对象 LambdaTest2,并且通过该对象来使用成员变量引用
    小贴士:
    如果先声明变量 obj,再使用 obj::sum 也是合法的。
public static void main(String[] args) {
    int a = 10;
    int b = 20;
    LambdaTest2 obj = new LambdaTest2();
    runIt(obj::sum, a, b);
}

总结

  • Lambda表达式的前置条件:必须是“函数式接口”
  • 单个参数传递时,可以省略参数两端的括号。参数的类型可以一起省略。
  • 编写的方式主要包括单行表达式和多行表达式
  • 可以使用方法引用来把多行表达式写成单行表达式。方法引用又包括了静态方法引用和动态方法引用。

标签:String,int,void,接口,Java8,public,表达式,lambda
来源: https://www.cnblogs.com/kendoziyu/p/java8-lambda-expression.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有