• 首页

  • 归档

  • 标签

  • 分类

  • 友链
M S B l o g
M S B l o g

ms

获取中...

09
03
java
总结

Java8:Lambad表达式

发表于 2020-09-03 • java 总结 java8 • 被 1,016 人看爆
  • Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。使用 Lambda 表达式可以使代码变的更加简洁紧凑。
  • Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包(注意和数学传统意义上的不同)。

Lambda语法:

(parameters) -> expression
或
(parameters) ->{ statements; }

特性:

  • 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
  • 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
  • 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
  • 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。

表达式实例

表达式的简单例子:

// 1. 不需要参数,返回值为 5  
() -> 5  
  
// 2. 接收一个参数(数字类型),返回其2倍的值  
x -> 2 * x  
  
// 3. 接受2个参数(数字),并返回他们的差值  
(x, y) -> x – y  
  
// 4. 接收2个int型整数,返回他们的和  
(int x, int y) -> x + y  
  
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)  
(String s) -> System.out.print(s)

在 Java8Test.java 文件输入以下代码:

package TestJava8;

public class Java8Test {
    public static void main(String[] args) {
        Java8Test test = new Java8Test();
        //类型声明
        MathOperation addition = (int a , int b) -> a + b;

        //不用类型声明
        MathOperation subtraction = (a , b) -> a - b;

        //大括号的返回语句
        MathOperation multiplication = (int a , int b) -> {return a * b;};

        //没有大括号以及返回语句
        MathOperation division = (int a , int b) -> a/b;

        System.out.println("10 + 5 = " + test.operate(10,5,addition));
        System.out.println("10 - 5 = " + test.operate(10,5,subtraction));
        System.out.println("10 * 5 = " + test.operate(10,5,multiplication));
        System.out.println("10 / 5 = " + test.operate(10,5,division));

        //不用括号
        GreetingService gerrtService = message ->
                System.out.println("hello" + message);

        //用括号
        GreetingService greetingService1 = (message) ->
                System.out.println("hello" + message);

        gerrtService.sayMessage("kugou");
        greetingService1.sayMessage("google");

    }
    interface MathOperation {
        int operation(int a, int b);
    }

    interface GreetingService {
        void sayMessage(String message);
    }

    private int operate(int a, int b, MathOperation mathOperation){
        return mathOperation.operation(a, b);
    }
}

执行代码,输出结果:

10 + 5 = 15
10 - 5 = 5
10 * 5 = 50
10 / 5 = 2
hellokugou
hellogoogle

将Lambad匹配到接口

单个抽象方法接口有时也称为函数式接口。将Java lambda表达式与函数式接口进行匹配需要以下步骤:

  • 接口是否只有一个抽象方法?
  • lambda表达式的参数是否与抽象方法的参数匹配?
  • lambda表达式的返回类型是否与抽象方法的返回类型匹配?
    如果这三个条件都满足,则该接口可以匹配给定的lambda表达式。

使用Lambda语法来代替匿名的内部类,代码不仅简洁,而且还可读

不采用Lambda的老方法:

Runnable runnable1=new Runnable(){
@Override
public void run(){
    System.out.println("Running without Lambda");
}
};

使用Lambad:

Runnable runnable = () -> System.out.println("Running without Lambda");

使用Lambda表达式不仅让代码变的简单、而且可读、最重要的是代码量也随之减少很多。

变量作用域

lambda 表达式只能引用标记了 final 的外层局部变量,这就是说不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误。

    final static String salutation = "Hello!";

    public static void main(String[] args) {
        GreetingService greetingService = message ->
                System.out.println(salutation + message);
        greetingService.sayMessage("KuGou");
    }

    interface GreetingService {
        void sayMessage(String message);
    }

执行代码,结果:

Hello!KuGou

也可以直接在 lambda 表达式中访问外层的局部变量:

    public static void main(String args[]) {
        final int num = 1;
        Converter<Integer, String> s = (param) -> System.out.println(String.valueOf(param + num));
        s.convert(2);  // 输出结果为 3
    }
 
    public interface Converter<T1, T2> {
        void convert(int i);
    }

lambda 表达式的局部变量可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)

int num = 1;  
Converter<Integer, String> s = (param) -> System.out.println(String.valueOf(param + num));
s.convert(2);
num = 5;  
//报错信息:Local variable num defined in an enclosing scope must be final or effectively 
 final

在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。

String first = "";  
Comparator<String> comparator = (first, second) -> Integer.compare(first.length(), second.length());  //编译会出错 
分享到:
[力扣]换座位
[力扣]无重复字符的最长子串
  • 文章目录
  • 站点概览
ms

MSms

⚓️HelloWorld⚓️

QQ Email RSS
看爆 Top5
  • MyBatis-Plus分页查询 5,936次看爆
  • @Autowired与@Resource的区别 4,755次看爆
  • feign远程调用及异步调用丢失请求头问题 4,526次看爆
  • spring cloud中OpenFeign整合Sentinel启动报错 4,423次看爆
  • Certbot查看证书过期时间,手动续期以及自动续期 3,302次看爆

Copyright © 2025 ms · 湘ICP备20015239号

Proudly published with Halo · Theme by fyang · 站点地图