首頁 >Java >java教程 >Java實例詳解之Lambda表達式

Java實例詳解之Lambda表達式

WBOY
WBOY轉載
2022-04-24 12:04:482176瀏覽

本篇文章為大家帶來了關於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);}
但是,使用匿名內部的方式,程式碼量其實並不是非常簡潔,而為了使程式碼更加的簡潔,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);}
透過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("跳的更高");
    }}
可以在介面上加**@FunctionalInterface

註解,去斷言這個接口是函數式接口,如果這個接口不是函數式接口,編譯就會提示錯誤。
Java實例詳解之Lambda表達式 為什麼要知道什麼是函數式介面呢?因為Lambda表達式去簡化一個介面的匿名類別實作方式,它只
能對函數式介面運作**。
這很容易理解,如果一個介面有多個待實現的方法,Lambda表達式就無法分辨出它現在是對介面中哪個方法進行實作。

三、Lambda表達式語法

Lambda表達式在Java語言中引入了一個運算元**“->”**,該運算符被稱為Lambda操作符或箭頭操作符。它將Lambda分為兩個部分:

左側:指定了Lambda表達式所需的所有參數

右側:制定了Lambda體,即Lambda表達式要執行的功能。
像這樣:

(parameters) -> expression
或
(parameters) ->{ statements; }
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();
    }
以下是lambda表達式的重要特徵:

  • 可選類型宣告:Lambda表達式可以不用宣告實作方法的參數類型,編譯器可以統一辨識參數值。
        // 类型声明
        MathOperation addition = (int a, int b) -> a + b;
        // 不用类型声明
        MathOperation subtraction = (a, b) -> a - b;
  • 可選的參數圓括號:一個參數不需要定義圓括號,但沒有參數或多個參數需要定義圓括號。
      // 不用括号
        GreetingService greetService1 = message ->
                System.out.println("Hello " + message);

        // 用括号
        GreetingService greetService2 = (message) ->
                System.out.println("Hello " + message);
  • 可選的大括號:如果主體包含了一個語句,就不需要使用大括號。
     // 多条语句不可以省略大括号
        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;
  • 可選的回傳關鍵字:如果主體只有一個表達式回傳值則編譯器會自動傳回值,大括號需要指定表達式回傳了一個數值。
  // 多条语句的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;
四、Lambda表達式的使用範圍

Lambda表達式不只是單單的用來簡化一個匿名類別的創建,它還有更多的用法。

1、為變數賦值

上文中,對Lambda表達式的用法都是為變數賦值的寫法,這樣可以簡化匿名內部類別賦值的程式碼段,提高閱讀效率。

MathOperation subtraction = (a, b) -> a - b;
2、作為return結果

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

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

3、作為陣列元素

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

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

五、 Lambda表達式的作用域範圍

Lambda表達式表達體內,可以存取表達體外的變量,但無法對其他變數進行修改操作。


Java實例詳解之Lambda表達式

六、Lambda表達式的引用寫法

在學習Lambda的時候,也可能會發現一種比較奇怪的寫法,例如下面的程式碼:

// 方法引用写法GreetingService greetingService = System.out::println;
        greetingService.sayMessage("hello world");
這裡出現了一個從來沒見過的符號:: ,這種寫法就叫做方法的引用。

顯然使用方法引用比普通的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<test> 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() {
    }}</test>

7、Lambda表达式的优缺点

优点:

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

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

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

缺点

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

推荐学习:《java视频教程

以上是Java實例詳解之Lambda表達式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除