1. 程式人生 > >Java8:Lambda簡單實戰

Java8:Lambda簡單實戰

Lambda表示式可以理解為一種匿名函式:它沒有名稱,但是由引數列表函式主體返回型別,當然可能還有一個可以丟擲的異常的列表

Lambda的基本語法是

(parameters) -> expression

或(請注意語句的花括號)

(parameters) -> { statements; }
根據上述語法規則,以下哪個不是有效的Lambda表示式?
(1) () -> {}
(2) () -> "Raoul"
(3) () -> {return "Mario";}
(4) (Integer i) -> return "Alan"
+ i; (5) (String s) -> {"IronMan";} 答案:只有45是無效的Lambda。 (1) 這個Lambda沒有引數,並返回void。它類似於主體為空的方法:public void run() {}。 (2) 這個Lambda沒有引數,並返回String作為表示式。 (3) 這個Lambda沒有引數,並返回String(利用顯式返回語句)。 (4) return是一個控制流語句。要使此Lambda有效,需要使花括號,如下所示: (Integer i) -> {return "Alan" + i;}。 (5)“Iron Man”是一個表示式,不是一個語句。要使此Lambda有效,你可以去除花括號 和分號,如下所示:(String s)
->
"Iron Man"。或者如果你喜歡,可以使用顯式返回語 句,如下所示:(String s)->{return "IronMan";}。

這裡我們從一個排序問題入手——用不同的排序策略來給一個Apple列表排序,我們從一個原始粗暴的解決方法一步步簡明清晰化。

這裡會用到一系列概念:行為引數化,匿名類,Lambda表示式和方法引用

下面是Apple類的定義:

    public static class Apple {
        private Integer weight = 0;
        private String color = "";

        public
Apple(Integer weight, String color) { this.weight = weight; this.color = color; } public Integer getWeight() { return weight; } public void setWeight(Integer weight) { this.weight = weight; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public String toString() { return "Apple{" + "color='" + color + '\'' + ", weight=" + weight + '}'; } }

第一步:傳遞程式碼

Java 8的API已經為我們提供了一個List可用的sort方法,我們不用自己去實現它。

那麼最困難的部分已經搞定了!但是,如何把排序策略傳遞給sort方法呢?
sort方法的簽名是這樣的:

void sort(Comparator<? super E> c)

它需要一個Comparator物件來比較兩個Apple!這就是在Java中傳遞策略的方式:它們必須包裹在一個物件裡。我們說sort的行為被引數化了:傳遞給它的排序策略不同,其行為也會不同

List<Apple> inventory = new ArrayList<>();
public static class AppleComparator implements Comparator<Apple> {
        public int compare(Apple a1, Apple a2) {
            return a1.getWeight().compareTo(a2.getWeight());
        }
    }
inventory.sort(new AppleComparator());

第二步:使用匿名內部類

第一步的方案可以使用匿名內部類來進行優化,因為一個AppleComparator 比較器可能就使用一次,我們不需要單獨建立一個類來實現它。

        inventory.sort(new Comparator<Apple>() {
            public int compare(Apple a1, Apple a2) {
                return a1.getWeight().compareTo(a2.getWeight());
            }
        });

第三步:使用Lambda表示式

使用匿名內部類的缺點:
1.它往往很笨重,佔用了很多程式碼空間,換句話來說,它太囉嗦了。
2.用起來讓人費解,邏輯不是很清晰。
Java 8中引入了Lambda表示式,它提供了一種輕量級的語法來實現相同的目標:傳遞程式碼。(放在我們這個問題裡就是傳遞策略,List#sort()方法根據不同的策略(程式碼)來實現不同的排序)。
在這個例子中,Comparator代表了函式描述符(T, T) -> int。因為我們比較的是蘋果,所以它具體代表的就是(Apple, Apple) -> int。

inventory.sort((Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight()));

因為,Java編譯器可以根據Lambda出現的上下文來推斷出Lamdba表示式引數的型別,那麼我們的解決方案可以改寫為:

inventory.sort((a1, a2) -> a1.getWeight().compareTo(a2.getWeight()));

到這裡我們依舊不滿足,Comparator具有一個叫作comparing的靜態輔助方法,它可以接受一個Function來提取Comparable鍵值,並生成一個Comparator物件。

    public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
            Function<? super T, ? extends U> keyExtractor)
    {
        Objects.requireNonNull(keyExtractor);
        return (Comparator<T> & Serializable)
            (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
    }

它可以像下面這樣用(注意你現在傳遞的Lambda只有一個引數:Lambda說明了如何從蘋果中提取需要比較的鍵值):

Comparator<Apple> c = Comparator.comparing((Apple a) -> a.getWeight());
inventory.sort(c);

這裡我們還可以把程式碼改的緊湊一些:

// 靜態導包
import static java.util.Comparator.comparing;
inventory.sort(comparing((a) -> a.getWeight()));

第四步:使用方法引用

方法引用就是替代那些轉發引數的Lambda表示式的語法糖。你可以用方法引用讓你的程式碼更簡潔(假設你靜態匯入了java.util.Comparator.comparing):

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

方法引用讓你重複使用現有的方法實現並直接傳遞它們。

恭喜你,這就是你的最終解決方案!這比Java 8之前的程式碼好在哪兒呢?

它比較短;它的意思也很明顯,並且程式碼讀起來和問題描述差不多:“對庫存進行排序,比較蘋果的重量。”

相關推薦

Java8:Lambda簡單實戰

Lambda表示式可以理解為一種匿名函式:它沒有名稱,但是由引數列表,函式主體,返回型別,當然可能還有一個可以丟擲的異常的列表。 Lambda的基本語法是 (parameters) -> expression 或(請注意語句的花括號)

Java8-2-Lambda表示式實戰-一句話實現Map中按照Value排序

今天我們來實戰一把, 對Map的Value值排序進行簡化. 在以前的思路我們的做法如下: /** Map根據value排序; @param map @return*/public static <K, V extends Comparable<? super V

Java8 Lambda表達式

ava nal oge void 參數 冒號 pub operator nis Lambda表達式是Java SE 8中一個重要的新特性。lambda表達式允許你通過表達式來代替功能接口。 lambda表達式就和方法一樣,它提供了一個正常的參數列表和一個使用這些參數的主體(

Java8 Lambda代碼備份

ring collector class student ati tor getname int() log 簡單研究了一下,貼出來,相當於筆記 import java.lang.reflect.*; import java.util.ArrayList; import

java8 lambda方法引用

*** display java8 接口 格式 arrays pareto nor 技術 註意引用方法的參數列表與返回值類型要與函數式接口中的抽象方法的參數列表與返回值類型保持一致 主要有三種語法格式: * * 對象::實例方法名 * * 類::靜態方法名 *

spark2.x由淺入深深到底系列六之RDD 支持java8 lambda表達式

spark lambda java8 老湯 rdd 學習spark任何技術之前,請正確理解spark,可以參考:正確理解spark我們在 http://7639240.blog.51cto.com/7629240/1966131 中已經知道了,一個scala函數其實就是java中的一個接口

移動端web開發初探之Vuejs的簡單實戰

參考 細節 重要 進行 標簽 樣式 mob 優化 view 這段時間在做的東西,是北郵人論壇APP的註冊頁。這個註冊頁是內嵌的網頁,因為打算安卓和IOS平臺同時使用。因此實際上就是在做移動端的web開發了。 在這過程中遇到了不少有意思的東西。 DEMO的github地址在這

Centos 7部署docker環境、基本命令使用及簡單實戰

方式 包括 socket stdin 兩種 輕松 本機 打開 root權限 Docker是一個開源的應用容器引擎,屬於Linux容器的一種封裝,是目前最流行的Linux容器解決方案。docker可以為任何應用創建一個輕量級、可移植的容器,然後容器可以運行在任何安裝有dock

Java8 Lambda( -> )&&方法引用( :: )&&函式式介面(@Functional)

一、簡述 Java8之前建立一個執行緒的程式碼: new Thread(new Runnable() { @Override public void run() { System.out.println("Test");

java8 lambda 處理List<Map<String,Integer>> 例項

最近遇到lambda 的表示式,總結了一下,,用一個稍微複雜的小例子 總結一下 public class streamTest {          @Test     public void lamb

jdk8 lambda表示式總結 Java8 lambda表示式10個示例

Java8 lambda表示式10個示例    1. 實現Runnable執行緒案例 使用() -> {} 替代匿名類: //Before Java 8: new Thread(new Runnable() { @Override

Java8——Lambda表示式入門

之前一直有聽說過Lambda表示式,但是一直也沒有使用過,最近學習了一下,感覺還不錯,簡單方便,把原來需要很多行才能實現的功能可以直接一行實現。不過最好也不要盲目的使用,並不是所有情況都適合用它! 引用一段大佬的話——超過3行的邏輯就不適用Lambda表示式了。雖然看著很先進,其實Lambd

Java Builder模式 Lambda表示式 Java8 lambda表示式10個示例

Java Builder模式 package com.cathay;/** * @Description * @TODO * @Author [email protected] * @Date 建立時間:2018/11/16 **/public class Person { private

java8--lambda表示式

java8中lambda表示式,類似c#中 lambda表示式,ES6中的箭頭函式 。   定義: 若java 介面中只有一個抽象方法,我們new 這個介面的例項時需要實現這個唯一的抽象方法,除此之外我們還可以使用一種新的表達方式來new這個介面的例項物件,這就是

Java8-lambda表示式總結

lambda表示式總結 lambda表示式是java8新特性,主要有如下極大用處 1.簡化匿名內部類 public class LambdaDemo { @Test public void test01() { // 使用匿名內部類

Java8 Lambda表示式原理掃盲

背景 在使用Lamdba表示式,一直以為是內部類的方式實現的,但是一想如果每次呼叫都例項化一個內部類,效能肯定不好,難道Java裡的lambda表示式真的是這麼實現的嗎?也許是該研究下原理了。 正文 測試程式碼: public class Test{ public void test

Okhttp3網路請求框架+MVP設計模式簡單實戰

Okhttp 目前最新版本的是okhttp:3.4.1,也稱為Okhttp3。  OkHttp是一個精巧的網路請求庫,不僅在介面封裝做的簡單易用,在底層實現上也自成一派。比起原生的HttpURLConnection有過之而無不及,現在已經成為廣大開發者的首選網路通訊庫。 特性 支援ht

Java8 lambda 的使用

摘要: 1.Java8 新特性介紹 2.專案中應用 1.Java8 新特性介紹 原文連結 https://my.oschina.net/chenxiaobian/blog/704421,https://www.cnblogs.com/hmdrzql/p/6354010.html

java8 lambda使用匯總

從java8出現以來lambda是最重要的特性之一,它可以讓我們用簡潔流暢的程式碼完成一個功能。 很長一段時間java被吐槽是冗餘和缺乏函數語言程式設計能力的語言,隨著函數語言程式設計的流行java8種也引入了 這種程式設計風格。在此之前我們都在寫匿名內部類幹這些事,但有時候這不是好的做

Lambda 簡單用例

package com.lambda.demo; import com.lambda.demo.exception.CanNotGetUserExceptionSupplier; import com.lambda.demo.model.User; import com.l