Heim > Java > Java-Tutorial > Hauptteil

Java实例详解之Lambda表达式

WBOY
Freigeben: 2022-04-24 12:04:48
nach vorne
2022 人浏览过

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于Lambda表达式的相关问题,Lambda表达式在Java语言中引入了一个操作符**“->”**,该操作符被称为Lambda操作符或箭头操作符,下面一起来看一下,希望对大家有帮助

Java实例详解之Lambda表达式

推荐学习:《java视频教程

一、Lambda初识

我们知道,在Java中,接口是不能实例化的,但是接口对象可以指向它的实现类对象。如果接口连实现对象都没有呢?那还可以使用匿名类的方式,如下:

public class JavaTest {
    public static void main(String[] args) {
        Fly fly = new Fly() {
            @Override
            public void fly(String name) {
                System.out.println(name + "飞行");
            }
        };
        fly.fly("张三");
    }}interface Fly{
    abstract void fly(String name);}
Nach dem Login kopieren

但是,使用匿名内部的方式,代码量其实并不是非常简洁,而为了使代码更加的简洁,Java引进了Lambda表达式的写法,通过更简单的语法,去实现这样功能,使用Lambda表达式简化的代码如下:

public class JavaTest {
    public static void main(String[] args) {
        Fly fly = name -> System.out.println(name + "飞行");
        fly.fly("张三");
    }}interface Fly{
    abstract void fly(String name);}
Nach dem Login kopieren

通过Lambda表达式完成了同样的效果,但是代码量却精简了非常对,这就是Lambda表达式的魅力。

二、 函数式接口

在学习Lambda表达式的语法之前,首先要知道什么是函数式接口, 只有一个待实现方法 的接口,就叫做函数式接口。

//接口中只有一个待实现的方法 fly,所以这是函数式接口interface Fly{
     void fly(String name);}//接口中有两个待实现的方法 这是不是函数式接口interface Run{
    void fastRun();
    void slowRun();}//接口中有两个方法,但其中一个是已经定义好的default方法,真正需要子类去实现的方法只有一个 这是函数式接口interface Jump{
    void jump();
    default void highJump(){
        System.out.println("跳的更高");
    }}
Nach dem Login kopieren

可以在接口上加**@FunctionalInterface注解,去断言这个接口是函数式接口,如果这个接口不是函数式接口,编译就会提示错误。
在这里插入图片描述
为什么要知道什么是函数式接口呢?因为Lambda表达式去简化一个接口的匿名类实现方式,它只
能对函数式接口起作用**。
这很容易理解,如果一个接口有多个待实现的方法,Lambda表达式就不能分辨出它现在是对接口中哪个方法进行实现。

三、Lambda表达式语法

Lambda表达式在Java语言中引入了一个操作符**“->”**,该操作符被称为Lambda操作符或箭头操作符。它将Lambda分为两个部分:

左侧:指定了Lambda表达式需要的所有参数
右侧:制定了Lambda体,即Lambda表达式要执行的功能。
像这样:

(parameters) -> expression
或
(parameters) ->{ statements; }
Nach dem Login kopieren

Lambda表达式的除了->和Lambda体,其他的比如参数,小括号,中括号都是可以更加参数类型、方法体代码行数进行省略的。
以如下函数式接口的实现为例:

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);
    }
    
    interface NoParam{
        int returnOne();
    }
Nach dem Login kopieren

以下是lambda表达式的重要特征:

  • 可选类型声明:Lambda表达式可以不用声明实现方法的参数类型,编译器可以统一识别参数值。
        // 类型声明
        MathOperation addition = (int a, int b) -> a + b;
        // 不用类型声明
        MathOperation subtraction = (a, b) -> a - b;
Nach dem Login kopieren
  • 可选的参数圆括号:一个参数无需定义圆括号,但没有参数或者多个参数需要定义圆括号。
      // 不用括号
        GreetingService greetService1 = message ->
                System.out.println("Hello " + message);

        // 用括号
        GreetingService greetService2 = (message) ->
                System.out.println("Hello " + message);
Nach dem Login kopieren
  • 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
     // 多条语句不可以省略大括号
        MathOperation multiplication = (int a, int b) -> {
            int num = a+1;
            num = a + b;
            return a * b + num;
        };

        // 单条语句可以省略大括号
        MathOperation pision = (int a, int b) -> a / b;
Nach dem Login kopieren
  • 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定表达式返回了一个数值。
  // 多条语句的Lambda表达式如果有返回值,需要使用return
        MathOperation multiplication = (int a, int b) -> {
            int num = a+1;
            num = a + b;
            return a * b + num;
        };

        // 单条语句可以省略return
        MathOperation pision = (int a, int b) -> a / b;
Nach dem Login kopieren

四、Lambda表达式的使用范围

Lambda表达式并不只是单单的用来简化一个匿名类的创建,它还有更多的用法。

1、为变量赋值

上文中,对Lambda表达式的用法都是为变量赋值的写法,这样可以简化匿名内部类赋值的代码段,提高阅读效率。

MathOperation subtraction = (a, b) -> a - b;
Nach dem Login kopieren

2、作为return结果

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

    MathOperation getOperation(int a, int b){
        return (a1, b1) -> a+b;
    }
Nach dem Login kopieren

3、作为数组元素

MathOperation math[] = {
                (a,b) -> a+b,
                (a,b) -> a-b,
                (a,b) -> a*b        };
Nach dem Login kopieren

4、作为普通方法或者构造方法的参数

public static void main(String args[]){

        Java8Tester java8Tester = new Java8Tester();
        java8Tester.operate(1,2,((a, b) -> a*b));

    }

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

    interface MathOperation {
        int operation(int a, int b);
    }
Nach dem Login kopieren

五、Lambda表达式的作用域范围

Lambda表达式表达体内,可以访问表达体外的变量,但无法对其他变量进行修改操作。
在这里插入图片描述

六、Lambda表达式的引用写法

在学习Lambda的时候,还可能会发现一种比较奇怪的写法,例如下面的代码:

// 方法引用写法GreetingService greetingService = System.out::println;
        greetingService.sayMessage("hello world");
Nach dem Login kopieren

这里出现了一个从来没见过的符号 :: ,这种写法就叫做方法的引用。
显然使用方法引用比普通的Lambda表达式又简洁了一些。

如果函数式接口的实现恰好可以通过调用一个方法来实现,那么我们可以使用方法引用。

public class Java8Tester {


    public static void main(String args[]){

        // 静态方法引用--通过类名调用
        GreetingService greetingService = Test::MyNameStatic;
        greetingService.sayMessage("hello");
        Test t = new Test();
        //实例方法引用--通过实例调用
        GreetingService greetingService2 = t::myName;
        // 构造方法方法引用--无参数
        Supplier supplier = Test::new;
        System.out.println(supplier.get());
    }



    interface GreetingService {
        void sayMessage(String message);
    }}class Test {
    // 静态方法
    public static void MyNameStatic(String name) {
        System.out.println(name);
    }

    // 实例方法
    public void myName(String name) {
        System.out.println(name);
    }

    // 无参构造方法
    public Test() {
    }}
Nach dem Login kopieren

7、Lambda表达式的优缺点

优点:

  • 更少的代码行-lambda表达式的最大好处之一就是减少了代码量。我们知道,lambda表达式只能与功能接口一起使用。例如,Runnable 是一个接口,因此我们可以轻松地应用lambda表达式。

  • 通过将行为作为方法中的参数传递来支持顺序和并行执行-通过在Java 8中使用Stream API,将函数传递给collection方法。现在,集合的职责是以顺序或并行的方式处理元素。

  • 更高的效率-过使用Stream API和lambda表达式,可以在批量操作集合的情况下获得更高的效率(并行执行)。 此外,lambda表达式有助于实现集合的内部迭代,而不是外部迭代。

缺点

  • 运行效率-若不用并行计算,很多时候计算速度没有比传统的 for 循环快。(并行计算有时需要预热才显示出效率优势)
  • 很难调试-Lambda表达式很难打断点,对调式不友好。
  • 不容易看懂-若其他程序员没有学过 lambda 表达式,代码不容易让其他语言的程序员看懂(我学Lambda表达式的原因是看不懂同事写的Lambda表达式代码)

推荐学习:《java视频教程

以上是Java实例详解之Lambda表达式的详细内容。更多信息请关注PHP中文网其他相关文章!

Verwandte Etiketten:
Quelle:csdn.net
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!