Java 8 Lambda 表达式

原文:https://www.studytonight.com/java-8/java-8-lambda-expression

Lambda 表达式是 Java 8 版本中引入的 Java 语言的一个特性。是一个没有名字的函数,使用函数方式执行代码。lambda 表达式也被称为匿名函数

它旨在提供函数式接口的实现。只有一个抽象方法的接口称为函数接口。Java 提供了一个注解@functional interface**,用来声明一个接口为函数接口。关于函数式接口的更多信息,请阅读我们在 Java 函数式接口上的帖子。

它使用较少的代码,并提供了一种清晰简洁的方式来表示一个方法接口。在集合库中,从集合中迭代、过滤和提取数据非常有用。

Lambda 表达式的优点

  • lambda 表达式的主体可以有一个或多个语句。

  • 如果只有一条语句,花括号是可选的。

  • return 语句是可选的,仅当方法签名具有返回类型时使用。

  • 我们可以向 lambda 表达式传递零个、一个或多个参数。

  • 参数的类型可以显式声明,也可以从上下文中推断出来。

  • 当有单个参数时,不一定要使用括号。括号是可选的。

句法

(list of arguments) -> { expression body}

参数列表可以是零、一或多个。

表达体可以有一个或多个语句。

Lambda 表达式的简短示例

我们可以认为 lambda 表达式是定义函数的一种聪明而简单的方法。如果您是初学者,那么我们建议您首先阅读 Java 中的函数函数接口

借助给定的基本示例,您可以获得 lambda 表达式的概念:

() -> System.out.println("executing lambda expression."); // zero argument, lambda expression

(String str) -> System.out.print(str); // single argumment, lambda expression

(int a, int b) -> a+b; // multiple arguments, sum of two values

(a,b) -> a+b // parameters without types, can be used to sum and concat two strings as well.

(int a, int b) -> return (a+b); // lambda expression with return statement

(int[]) -> { multiple statments; return index; }   // it can have multiple statements

在这些示例中,我们有各种各样的 lambda 表达式,如零参数单语句多参数lambda 带返回语句等。虽然返回语句是可选的,也可以有多个语句

还有一点,类型的参数是可选的这意味着如果我们不提供它,那么编译器会自动干预参数的类型,这被称为类型推断

现在让我们创建一些有趣的例子来理解 lambda 函数的用法。

Java 8 之前的场景

假设我们有一个包含单个抽象方法的接口,如果我们使用以前的 Java 8 提供它的实现,那么我们必须使用匿名类概念,代码看起来太乱了。请参见下面使用匿名类的示例

interface Runnable{  
    public void run();  
}  
public class Demo {  
    public static void main(String[] args) {  
        int speed=100;  

        // old approach to implement   
        Runnable r=new Runnable(){  
            public void run(){System.out.println("Running at the speed of "+speed);}  
        };  
        r.run();  
    }  
}

示例:场景 Java 8 及更高版本

从 Java 8 和更高版本,我们可以使用 lambda 表达式实现这样的抽象方法。这就是 lambda 表达式的优势,请注意它没有任何名称,这就是它也被称为匿名函数的原因。

interface Runnable{  
    public void run();  
}  
public class Demo {  
    public static void main(String[] args) {  
        int speed=100;  

        // new approach (lambda expression) to implement   
        Runnable r=()->{  
            System.out.println("Running at the speed of "+speed);  
        };  
        r.run();  
    }  
}

以 100 的速度奔跑

示例:带参数的 Lambda 表达式

Lambda 表达式可以有零个、一个或多个参数,就像我们使用方法一样。参数的类型是由 lambda 推断出来的,所以它是可选的,我们可能会也可能不会提到参数。请看例子,其中第二个 Lambda 表达式我们提到了参数的类型。

interface Runnable{  
    public void run(int speed);  
}  
public class Demo {  
    public static void main(String[] args) {  
        int speed=100;  

        // lambda expression:   
        Runnable r=(carSpeed)->{  
            System.out.println("Running at the speed of "+carSpeed);  
        };  
        r.run(speed);
        // specifying type of parameters
        Runnable r1=(int carSpeed)->{  
            System.out.println("Running at the speed of "+carSpeed);  
        }; 
        r1.run(speed);
    }  
}

以 100 的速度奔跑

示例:使用返回语句的 Lambda 表达式

return 语句是可选的,带有 lambda 表达式。我们可以使用它向调用者返回一个值,在这个例子中,我们使用了两个 lambda 表达式,其中第一个不使用 return 语句,而第二个使用 return 语句。

interface Runnable{  
    public String run(int speed, int distance);
}  
public class Demo {  
    public static void main(String[] args) {    

        // lambda expression: without return   
        Runnable r = (carSpeed,distance)->  
            ("Distance covered "+ distance +"Km at the speed of "+carSpeed);
        // calling
        String r15 = r.run(80,150);
        System.out.println(r15);
        // lambda expression: with return statement
        Runnable r1 = (int carSpeed, int distance)->{ 
            return ("Distance covered "+ distance +"Km at the speed of "+carSpeed);
        };
        String fz = r1.run(100,200);
        System.out.println(fz);

    }  
}

以 80 的速度行驶 150 公里 以 100 的速度行驶 200 公里

示例:集合中的 Lambda 表达式

虽然我们可以在任何地方使用 lambda 表达式来实现一个函数接口,但是这里我们使用它来迭代集合元素。这里我们使用了迭代器接口的 forEach()方法。

import java.util.ArrayList;
import java.util.List;

public class Demo {  
    public static void main(String[] args) {    

        List<Integer> list = new ArrayList<>();
        list.add(10);
        list.add(20);
        list.add(30);
        list.add(40);
        // Traversing using foreach
        System.out.println("Traversing using foreach");
        for(Integer element: list) {
            System.out.println(element);
        }
        // lambda expression
        System.out.println("Traversing using lambda expression");
        list.forEach(element->System.out.println(element));
    }  
}

使用 foreach 进行穿越 10 20 30 40 使用 lambda 表达式进行穿越 10 20 30 40

示例:使用 Lambda 的线程实现

Java Runnable 接口是一个包含单个抽象方法的函数式接口。我们可以使用 lambda 表达式实现它的 run()方法,并创建线程实例,就像我们在下面的示例中所做的那样。

public class Demo {  
    public static void main(String[] args) {    

        // Thread Implementation using anonymous class
        Runnable run = new Runnable() {
            public void run() {
                System.out.println("Thread running...");
            }
        };
        new Thread(run).start();

        // Thread Implementation using lambda expression
        Runnable run1 = ()->System.out.println("Thread Running using lambda...");
        new Thread(run1).start();

    }  
}

线程运行... 使用λ运行线程...