Lambda 表达式

简介: Lambda 表达式

引言



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


一、语法格式



基本语法


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


Lambda表达式由三部分组成:


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


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


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


二、理解函数式接口



定义


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


注意:如果我们在某个接口中声明了 @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();
    }
}


输出结果:


2c40c2aad5324929a4fd0256075fe6cb.png


程序清单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));
    }
}


输出结果:


100e808ca72f4f28ae7e2d3e701e0d0e.png


四、变量捕获



程序清单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();
    }
}


输出结果:


7fdf0cc5f4c54093954063e2bfc4047f.png


五、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);
    }
}


输出结果:


12694f769d4245219feb34e8004e34ee.png


六、Lambda 表达式的优缺点



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


优点:


① 代码简洁,开发迅速

② 方便函数式编程

③ 非常容易进行并行计算

④ Java 引入 Lambda,改善了集合操作


缺点:


① 代码可读性变差

② 在非并行计算中,很多计算未必有传统的 for 性能要高

③ 不容易进行调试


目录
相关文章
|
2月前
|
C#
C#一分钟浅谈:Lambda 表达式和匿名方法
本文详细介绍了C#编程中的Lambda表达式与匿名方法,两者均可用于定义无名函数,使代码更简洁易维护。文章通过基础概念讲解和示例对比,展示了各自语法特点,如Lambda表达式的`(parameters) =&gt; expression`形式及匿名方法的`delegate(parameters)`结构。并通过实例演示了两者的应用差异,强调了在使用Lambda时应注意闭包问题及其解决策略,推荐优先使用Lambda表达式以增强代码可读性。
41 8
|
5月前
|
算法 编译器
lambda 表达式
lambda 表达式
|
6月前
|
存储 JavaScript 前端开发
c++lambda函数与表达式
c++lambda函数与表达式
34 1
|
安全 架构师 Java
必须掌握的 Lambda 表达式
必须掌握的 Lambda 表达式
5896 1
必须掌握的 Lambda 表达式
|
算法 编译器
【lambda函数】lambda()函数
【lambda函数】lambda()函数
|
存储 算法 编译器
C++ lambda 表达式
# C++ `lamdba` 表达式 > Lambda表达式是C++11引入的一个新特性,它允许我们在需要函数对象的地方,使用一种更加简洁的方式定义匿名函数。Lambda表达式通常用于`STL`中的算法、回调函数、事件处理程序等场合。 Lambda表达式的基本语法为: ```c++ Copy Code[capture list](parameter list) mutable exception -> return type { function body } ``` ## `lamdba`表达式在什么场合下使用 C++11 lambda表达式可以用来创建匿名函数,也就是没有函数名的
95 0
|
Java
Lambda 表达式Demoo
Lambda 表达式Demoo
117 0
Lambda 表达式Demoo
|
存储 算法 编译器
【C++】lambda 表达式 | 包装器
【C++】lambda 表达式 | 包装器
【C++】lambda 表达式 | 包装器
|
Java 编译器
深入理解 Lambda 表达式
Java 8 的 Lambda 表达式已经不再是“新特性”。 现在很多人工作中会使用 Lambda 表达式。 但是,你是否真正理解 Lambda 表达式的底层原理?
403 0
深入理解 Lambda 表达式
|
Java 程序员
Lambda 表达式
Lambda 表达式