Java 8 Lambda 方法引用 簡記

来源:https://www.cnblogs.com/cndada/archive/2023/02/25/17153944.html
-Advertisement-
Play Games

Lambda 表達式以及方法引用 Java 8 的新特性筆記,重點講的是: Lambda 函數式介面 方法引用 Steam 流 Lambda 表達式 Lambda 的基礎使用不記錄,記錄 JDK 8 實戰 書上的一些底層和核心筆記。 行為參數化 一個貫徹 Lambda 表達式的一個模式、編程規範。 ...


Lambda 表達式以及方法引用

Java 8 的新特性筆記,重點講的是:

  • Lambda 函數式介面
  • 方法引用
  • Steam 流

Lambda 表達式

Lambda 的基礎使用不記錄,記錄 JDK 8 實戰 書上的一些底層和核心筆記。

行為參數化

一個貫徹 Lambda 表達式的一個模式、編程規範。

語句拆解:

  • 行為:就是一個方法或函數
  • 參數化:將原來的具體行為,變成一個參數,這個行為就是可變的,適用於多種場景。

主要的思想是:

eg:在某一個業務場景中,有一段業務代碼,可能需要對一個參數進行一些主要的篩選判斷,最後符合條件的才能添加到列表中。

// 過濾蘋果的主要方法
// Predicate 比較
public static List<Apple> filterApples(List<Apple> inventory){
    List<Apple> result = new ArrayList<>();
    for(Apple apple : inventory){
        if(條件篩選){ // 是否符合被篩選的條件
            result.add(apple);
        }
    }
    return result;
}

通過上面這段代碼,可以看到,這段代碼的核心處理起始只有條件篩選這塊,通過篩選後最後返回一個 boolean 值,為 ture 才能將蘋果添加到列表中最終返回。

所以條件篩選的可能有許多不同的具體實現,但是毋庸置疑的是最終都需要返回一個 boolean來決定是否滿足將蘋果添加至列表的操作。

所以我們將條件篩選這個行為參數化,來優化代碼,並使其更好擴展和維護。具體的實現可以直接百度 行為參數化 的詳細介紹。

主要是將這個行為參數化的目的。

Java 8 內置的一些常用函數式介面:

大部分日常能用到的在:java.util.function 包下。

註意:函數式介面一般會在類上加上註解 @FunctionalInterface 標識這個是函數式介面。

Lambda 表達式的使用前提是函數式介面

Lambda 的類型檢查、類型推斷以及限制

類型檢查:

類型檢查很好理解,根據使用 Lambda 的上下文(例如,接受它傳遞的方法的參數,或者接受它的值的局部變數)推斷出來的,上下文中使用 Lambda 的類型稱為 目標類型 (就是使用哪個具體的類使用Lambda),根據目標類型(肯定是一個函數式介面)中的抽象方法簽名來對應 Lambda 表達式的簽名(包括抽象方法中聲明的 throws 異常),檢查這個 Lambda 表達式是否符合規範。

特殊的 void 相容規則:

如果一個Lambda的主體是一個語句表達式, 它就和一個返回 void 的函數描述符相容(當然需要參數列表也相容)。

eg:以下兩行都是合法的,儘管 List 的 add 方法返回了一個boolean ,而不是 Consumer 上下文( T -> void )所要求的 void。

List<String> stringList = new ArrayList<>();
// Predicate返回了一個boolean
Predicate<String> predicate = s -> stringList.add(s); 
// Consumer返回了一個void
Consumer<String> consumer = s -> stringList.add(s);

類型推斷:

使用 Lambda 表達式,如果至少有一個參數,則可以顯示的說明參數的具體類型,同時也可以不顯示說明,只寫形參名,則會觸發 Java 編譯器的類型推斷機制,根據上下文來推斷 Lambda 表達式的參數類型。

註意:如果只有一個參數還可以省去參數兩邊的括弧。

限制:使用局部變數

Lambda 表達式允許使用自由變數(實例變數,靜態變數)以及局部變數,但是在使用局部變數時有限制。

我們必須保證 Lambda 表達式引用的局部變數最終是 final,也就是說使用的是局部變數的副本,而不是直接去訪問原始變數。

因為局部變數存在棧中,這個和 Lambda 執行時線程安全相關。

在使用實例變數時,可以改變賦值(引用地址),因為這些變數保存在堆中,而堆是線上程之間共用的

方法引用

Java 8 的另一個功能:方法引用,某些 Lambda 的快捷寫法。

基本思想:如果 Lambda 代表的只是 “直接調用這個方法”,可以直接用名稱調用它,而不是去描述如何調用。

使用方法:目標引用 :: 方法名稱

複合 Lambda 表達式的有用方法

例如:Comparator、Function 和 Predicate 都提供了允許你進行複合的方法。

比較器複合(Comparator)

List<Apple> inventory = Arrays.asList(Apple...);

  1. 逆序

    inventory.sort(Comparator.comparing(Apple::getWeight).reversed());

  2. 比較器鏈:thenComparing() 如果一樣,則按照指定的規則排序

    inventory.sort(Comparator.comparing(Apple::getWeight).thenComparing(Apple::getColor));

謂詞複合(Predicate)

介面包含三個預設方法:negate、and 和 or,重用已有的 Predicate 來創建更複雜的謂詞。

redApple 是現有的 Predicate 的實例。

  1. negate:

    表示此謂詞的邏輯否定的謂詞。

    Predicate<Apple> notRedApple = redApple.negate(); -- > 蘋果不是紅色的

  2. and:

    該謂詞表示此謂詞與另一個謂詞的短路邏輯AND。在計算組合謂詞時,如果此謂詞為假,則不計算其他謂詞。

    Predicate<Apple> redAndHeavyApple = redApple.and(a -> a.getWeight() > 150); -- > 蘋果又紅又重。

  3. or:

    一個組合謂詞,該謂詞表示此謂詞與另一個謂詞的短路邏輯或。在計算組合謂詞時,如果此謂詞為真,則不計算其他謂詞。

    Predicate<Apple> redAndHeavyApple = redApple.and(a -> a.getWeight() > 150).or(a -> "green".equals(a.getColor())); -- > 要麼蘋果又紅又重,要麼就是綠蘋果。

函數複合(Function)

compose()

andThen()

兩者都是函數的複合,其主要區別是:

  • compose:f.compose(g),先調用 g 再調用 f
  • andThen:f.andThen(g) ,先調用 f 在調用 g

可以用作流水線模式。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 實驗指南 這篇博客旨在實驗客戶端和服務端相互發送消息的實驗,實驗成功的現象為,客戶端和服務端的兩個視窗,即client和server左上角均被打上文字,因為客戶端是沒有給圖片附上文字的功能的,十分感謝柒上夏OPO大佬提供源碼上的支持 客戶端代碼 import numpy as np import c ...
  • 哈嘍兄弟,今天給大家分享一個Python tkinter製作法律查詢小工具。 光爬蟲大家也只能自己用用,就算打包了exe,運行也不好看,那我們直接寫成界面。 當我們想瞭解法律,但是又不想買書的時候,就可以用這個小工具,慢慢查詢瞭解。 當然,如果想整的比較有意思,就得靠大家自己來完善實現了。 效果展示 ...
  • 原生的API&註解方式 1.MyBatis原生的API調用 1.1原生API快速入門 需求:在前面的項目基礎上,使用MyBatis原生的API完成,即直接通過SqlSession介面的方法來完成操作 1.2代碼實現 MyBatisNativeTest.java,演示原生的API操作 其實底層還是使用 ...
  • 一、什麼是模塊? 模塊是一系列功能的集合體,而函數是某一個功能的集合體,因此模塊可以看成是一堆函數的集合體。一個py文件內部就可以放一堆函數,因此一個py文件就可以看成一個模塊。如果這個py文件的文件名為module.py,模塊名則是module。 二、模塊的四種形式 在Python中,總共有以下四 ...
  • 一、單元測試框架簡介 1. 什麼是單元測試 單元測試是指在軟體開發過程中,針對軟體的最小單位(函數,方法)進行正確性的檢查測試。 2. 常用單元測試框架 2.1 Java 類別 junit testng 2.2 Python 類別 unittest pytest 3. 單元測試框架主要作用 測試發現 ...
  • 【深進1.例1】求區間和 題目描述 給定 $n$ 個正整數組成的數列 $a_1, a_2, \cdots, a_n$ 和 $m$ 個區間 $[l_i,r_i]$,分別求這 $m$ 個區間的區間和。 輸入格式 共 $n+m+2$ 行。 第一行,為一個正整數 $n$ 。 第二行,為 $n$ 個正整數 $ ...
  • 原創:扣釘日記(微信公眾號ID:codelogs),歡迎分享,非公眾號轉載保留此聲明。 簡介 日常編程工作中,Java集合會經常被使用到,且經常需要對集合做一些類似過濾、排序、對象轉換之類的操作。 為了簡化這類操作,Java8添加了一套新的Stream API,使用方式就像寫SQL一樣,大大簡化了這 ...
  • 這篇文章主要描述分散式數據存儲系統中的數據分片方法,包括哈希方法、一致性哈希方法、帶有限負載的一致性哈希方法以及帶虛擬節點的一致性哈希方法。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...