首頁 Java java教程 Java8新特性之Lambda表達式淺析

Java8新特性之Lambda表達式淺析

Jan 23, 2017 pm 03:33 PM

說到java 8,首先會想到lambda(閉包)以及虛擬擴展方法(default method),這個特性早已經被各大技術網站炒得沸沸揚揚了,也是我們java 8系列開篇要講的第一特性( JEP126 http://openjdk.java.net/jeps/126),jdk8的部分函式庫已經應用了lambda表達式重新設計了,理解他對學習java 8新特性有著重要的意義。

一、函數式介面

函數式介面(functional interface 也叫功能性接口,其實是同一個東西)。簡單來說,函數式介面是只包含一個方法的介面。例如Java標準函式庫中的java.lang.Runnable和java.util.Comparator都是典型的函式介面。 java 8提供@FunctionalInterface作為註解,這個註解是非必須的,只要介面符合函數式介面的標準(即只包含一個方法的介面),虛擬機會自動判斷,但最好在介面上使用註解@FunctionalInterface進行聲明,以免團隊的其他人員錯誤地往介面中新增新的方法。
Java中的lambda無法單獨出現,它需要一個函數式介面來盛放,lambda表達式方法體其實就是函數介面的實現,下面講到語法會講到

二、Lambda語法

包含三個部分

1.一個括號內用逗號分隔的形式參數,參數是函數式介面裡面方法的參數

2.一個箭頭符號:->

3.方法體,可以是表達式和程式碼區塊,方法體函數式介面裡面方法的實現,如果是程式碼區塊,必須用{}來包裹起來,且需要一個return 回傳值,但有個例外,若函數式介面裡面方法回傳值是void,則不需要{}

整體看起來像這樣:

(parameters) -> expression 或者 (parameters) -> { statements; }
登入後複製

看一個完整的例子,方便理解

/**
 * 测试lambda表达式
 *
 * @author benhail
 */
public class TestLambda {
    public static void runThreadUseLambda() {
        //Runnable是一个函数接口,只包含了有个无参数的,返回void的run方法;
        //所以lambda表达式左边没有参数,右边也没有return,只是单纯的打印一句话
        new Thread(() ->System.out.println("lambda实现的线程")).start(); 
    }
    public static void runThreadUseInnerClass() {
        //这种方式就不多讲了,以前旧版本比较常见的做法
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("内部类实现的线程");
            }
        }).start();
    }
    public static void main(String[] args) {
        TestLambda.runThreadUseLambda();
        TestLambda.runThreadUseInnerClass();
    }
}
登入後複製

可以看出,使用lambda表達式設計的程式碼會更加簡潔,而且還可讀。

三、方法引用

其實是lambda表達式的一個簡化寫法,所引用的方法其實是lambda表達式的方法體實現,語法也很簡單,左邊是容器(可以是類別名,實例名),中間是"::",右邊是對應的方法名稱。如下圖所示:

ObjectReference::methodName
登入後複製

一般方法的參考格式是

如果是靜態方法,則是ClassName::methodName。如 Object ::equals

如果是實例方法,則是Instance::methodName。如Object obj=new Object();obj::equals;

建構子.則是ClassName::new

再來看一個完整的例子,方便理解:

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
/**
 *
 * @author benhail
 */
public class TestMethodReference {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setLayout(new FlowLayout());
        frame.setVisible(true);

        JButton button1 = new JButton("点我!");
        JButton button2 = new JButton("也点我!");

        frame.getContentPane().add(button1);
        frame.getContentPane().add(button2);
        //这里addActionListener方法的参数是ActionListener,是一个函数式接口
        //使用lambda表达式方式
        button1.addActionListener(e -> { System.out.println("这里是Lambda实现方式"); });
        //使用方法引用方式
        button2.addActionListener(TestMethodReference::doSomething);

    }
    /**
     * 这里是函数式接口ActionListener的实现方法
     * @param e 
     */
    public static void doSomething(ActionEvent e) {

        System.out.println("这里是方法引用实现方式");

    }
}
登入後複製

可以看出,doSomething方法就是lambda表達式的實現,這樣的好處就是,如果你覺得lambda的方法體會很長,影響程式碼可讀性,方法引用就是個解決辦法

四、總結

以上就是lambda表達式語法的全部內容了,相信大家對lambda表達式都有一定的理解了,但只是程式碼簡潔了這個好處的話,並不能打動很多觀眾,java 8也不會這麼令人期待,其實java 8引入lambda迫切需求是因為lambda 表達式能簡化集合上資料的多執行緒或多核心的處理,提供更快的集合處理速度,這個後續會講到,關於JEP126的這一特性,將分3部分,之所以分開,是因為這一特性可寫的東西太多了,這部分讓讀者熟悉lambda表達式以及方法引用的語法和概念,第二部分則是虛擬擴展方法(default method)的內容,最後一部分則是大數據集合的處理,解開lambda表達式的最強作用的神秘面紗。

更多Java8新特性之Lambda表達式淺析相關文章請關注PHP中文網!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

公司安全軟件導致應用無法運行?如何排查和解決? 公司安全軟件導致應用無法運行?如何排查和解決? Apr 19, 2025 pm 04:51 PM

公司安全軟件導致部分應用無法正常運行的排查與解決方法許多公司為了保障內部網絡安全,會部署安全軟件。 ...

如何使用MapStruct簡化系統對接中的字段映射問題? 如何使用MapStruct簡化系統對接中的字段映射問題? Apr 19, 2025 pm 06:21 PM

系統對接中的字段映射處理在進行系統對接時,常常會遇到一個棘手的問題:如何將A系統的接口字段有效地映�...

如何優雅地獲取實體類變量名構建數據庫查詢條件? 如何優雅地獲取實體類變量名構建數據庫查詢條件? Apr 19, 2025 pm 11:42 PM

在使用MyBatis-Plus或其他ORM框架進行數據庫操作時,經常需要根據實體類的屬性名構造查詢條件。如果每次都手動...

如何將姓名轉換為數字以實現排序並保持群組中的一致性? 如何將姓名轉換為數字以實現排序並保持群組中的一致性? Apr 19, 2025 pm 11:30 PM

將姓名轉換為數字以實現排序的解決方案在許多應用場景中,用戶可能需要在群組中進行排序,尤其是在一個用...

IntelliJ IDEA是如何在不輸出日誌的情況下識別Spring Boot項目的端口號的? IntelliJ IDEA是如何在不輸出日誌的情況下識別Spring Boot項目的端口號的? Apr 19, 2025 pm 11:45 PM

在使用IntelliJIDEAUltimate版本啟動Spring...

Java對像如何安全地轉換為數組? Java對像如何安全地轉換為數組? Apr 19, 2025 pm 11:33 PM

Java對象與數組的轉換:深入探討強制類型轉換的風險與正確方法很多Java初學者會遇到將一個對象轉換成數組的�...

電商平台SKU和SPU數據庫設計:如何兼顧用戶自定義屬性和無屬性商品? 電商平台SKU和SPU數據庫設計:如何兼顧用戶自定義屬性和無屬性商品? Apr 19, 2025 pm 11:27 PM

電商平台SKU和SPU表設計詳解本文將探討電商平台中SKU和SPU的數據庫設計問題,特別是如何處理用戶自定義銷售屬...

使用TKMyBatis進行數據庫查詢時,如何優雅地獲取實體類變量名構建查詢條件? 使用TKMyBatis進行數據庫查詢時,如何優雅地獲取實體類變量名構建查詢條件? Apr 19, 2025 pm 09:51 PM

在使用TKMyBatis進行數據庫查詢時,如何優雅地獲取實體類變量名以構建查詢條件,是一個常見的難題。本文將針...

See all articles