Lambda 表达式

引言

Lambda 表达式是 Java SE 8 中一个重要的新特性。其允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(可以是一个表达式或一个代码块)。 此外,Lambda 表达式也可以看作是一个匿名函数,基于数学中的 λ 演算得名,也称为闭包。

一、语法格式

基本语法

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

Lambda表达式由三部分组成:

  1. paramaters:类似方法中的形参列表,这里的参数即为函数式接口里的参数。这里的参数类型可以明确声明,也可不声明,可由 JVM 推断。此外,当只有一个paramaters时,可以省略掉其对应圆括号。

  2. ->:可理解为“被用于”的意思。

  3. 方法体:可以是表达式也可以是代码块,是函数式接口里方法的实现。代码块可返回一个值或什么都不返回,这里的代码块等同于方法的方法体。如果是表达式,也可以返回一个值或者什么都不返回。

二、理解函数式接口

定义

如果一个接口有且仅有一个抽象方法,那么该接口称为函数式接口。

注意:如果我们在某个接口中声明了 @FunctionalInterface 注解,那么编译器就会按照函数式接口的定义来要求该接口。显然,当我们定义了两个抽象方法,程序编译就会报错。下面为函数式接口的语法

@FunctionalInterface
interface NoParameterNoReturn {
	void test(); //注意:只能有一个抽象方法
}

三、使用 Lambda 表达式

程序清单1:

interface NoParameterNoReturn{
    void test();
}

public class Test1 {
    public static void main(String[] args) {
        
        //1. 正常实现一个接口
        //一般来说,接口不能直接通过 new 来实例化对象
        //但是我们可以通过 new 一个对象,相当于一个匿名内部类实现了此接口,
        //并重写其方法
        NoParameterNoReturn noParameterNoReturn = new NoParameterNoReturn() {
            @Override
            public void test() {
                System.out.println("重写方法");
            }
        };
        noParameterNoReturn.test();
        System.out.println("-----------------");
        
        //2. 使用 Lambda 表达式
        NoParameterNoReturn noParameterNoReturn2 = () -> System.out.println("重写方法");
        noParameterNoReturn2.test();
    }
}

输出结果:

out
程序清单2:

/**
 * 通过使用 Lambda 表达式来测试一些接口
 */
interface OneParameterNoReturn {
    void test(int a);
}

interface MoreParameterNoReturn {
    void test(int a,int b);
}

interface NoParameterReturn {
    int test();
}

interface OneParameterReturn {
    int test(int a);
}

interface MoreParameterReturn {
    int test(int a,int b);
}

public class Test2 {
    public static void main(String[] args) {
        //1. 一个参数无返回值
        //形式一
        OneParameterNoReturn oneParameterNoReturn = (a)-> {System.out.println(a);};
        //形式二
        OneParameterNoReturn oneParameterNoReturn2 = a-> System.out.println(a);
        oneParameterNoReturn2.test(10);
        System.out.println("----------------------");

        //2. 多个参数无返回值
        //形式一
        MoreParameterNoReturn moreParameterNoReturn = (int a, int b)->{
            System.out.println(a+b);
        };
        //形式二
        MoreParameterNoReturn moreParameterNoReturn2 = (a,b)-> System.out.println(a+b);
        moreParameterNoReturn2.test(10,20);
        System.out.println("----------------------");

        //3. 无参数有返回值
        //形式一
        NoParameterReturn noParameterReturn = ()->{return 111;};
        //形式二
        NoParameterReturn noParameterReturn2 = ()->111;
        System.out.println(noParameterReturn2.test());
        System.out.println("----------------------");

        //4. 一个参数有返回值
        OneParameterReturn oneParameterReturn = (a)->a+5;
        System.out.println(oneParameterReturn.test(100));
        System.out.println("----------------------");

        //5. 多个参数有返回值
        MoreParameterReturn moreParameterReturn = (a,b)->a*b;
        System.out.println(moreParameterReturn.test(5, 5));

    }
}

输出结果:

out

四、变量捕获

程序清单3:

/**
 * 变量捕获
 */

class Out{
    public void function(){
        System.out.println(123);
    }
}

interface NoParameterNoReturn2 {
    void test();
}

public class Test3 {
    public static void main(String[] args) {
        //1. 将 x 这个变量视为常量,或者这个 x 变量不能被修改
        //这样一来,下面的匿名内部类才能捕获到变量 x
        int x = 111;
        //x = 999; //error
        new Out(){
            @Override
            public void function() {
                System.out.println("捕获变量: " + x);
            }
        }.function();

        //2. 同理,下面是 Lambda 的变量捕获
        int a = 333;
        //a = 999; //error
        NoParameterNoReturn2 noParameterNoReturn2 = ()->{

            System.out.println("捕获变量:"+ a);
        };
        noParameterNoReturn2.test();
    }
}

输出结果:
out

五、Lambda在集合当中的使用

程序清单4:

import java.util.ArrayList;
import java.util.Comparator;
import java.util.function.Consumer;

/**
 * Lambda 表达式在集合当中的使用
 */

public class Test4 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("hello");
        list.add("world");
        list.add("nice");

        /**
         * 1. 打印出来 list 中的现有元素
         * 方法一:
         * 直接通过匿名内部类实现 Consumer 这个函数式接口
         */
        list.forEach(new Consumer<String>() {
            @Override
            public void accept(String str) {
                System.out.println(str);
            }
        });
        System.out.println("---------------------");

        //方法二:
        //Lambda 表达式的应用
        list.forEach(str -> System.out.println(str));
        System.out.println("---------------------");

        /**
         * 2. 排序 list 中的现有元素
         * 方法一:
         * 直接通过 Comparator 这个函数式接口 new 一个对象
         */
        list.sort(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });
        System.out.println(list);
        System.out.println("---------------------");

        //方法二:
        //Lambda 表达式的应用
        list.sort((o1, o2) -> o1.compareTo(o2));
        System.out.println(list);

    }
}

输出结果:

out

六、Lambda 表达式的优缺点

Lambda表达式的优点很明显,在代码层次上来说,使代码变得非常的简洁。缺点也很明显,代码不易读。

优点:

① 代码简洁,开发迅速
② 方便函数式编程
③ 非常容易进行并行计算
④ Java 引入 Lambda,改善了集合操作

缺点:

① 代码可读性变差
② 在非并行计算中,很多计算未必有传统的 for 性能要高
③ 不容易进行调试

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十七ing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值