日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

《Java8实战》笔记(03):Lambda表达式

發布時間:2023/12/13 java 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《Java8实战》笔记(03):Lambda表达式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文源碼

Lambda 管中窺豹

可以把Lambda表達式理解為簡潔地表示可傳遞的匿名函數的一種方式:它沒有名稱,但它有參數列表、函數主體、返回類型,可能還有一個可以拋出的異常列表。

Lambda表達式可以讓你十分簡明地傳遞代碼。


Lambda組成結構

  • 參數列表——這里它采用了Comparator中compare方法的參數,兩個Apple。
  • 箭頭——箭頭->把參數列表與Lambda主體分隔開。
  • Lambda主體——比較兩個Apple的重量。表達式就是Lambda的返回值了。

Lambda的基本語法是

(parameters) -> expression

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

(parameters) -> { statements; }

Java8先前:

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

Java8之后(用了Lambda表達式):

Comparator<Apple> byWeight = (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());

Java 8中有效的Lambda表達式

(String s) -> s.length()(Apple a) -> a.getWeight() > 150(int x, int y) -> {System.out.println("Result:");System.out.println(x+y); }() -> 42(Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight())
使用案例Lambda示例
布爾表達式(List list) -> list.isEmpty()
創建對象() -> new Apple(10)
消費一個對象(Apple a) -> {System.out.println(a.getWeight());}
從一個對象中選擇/抽取(String s) -> s.length()
組合兩個值(int a, int b) -> a * b
比較兩個對象(Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight())

在哪里以及如何使用Lambda

你可以在函數式接口上使用Lambda表達式。

在上面的代碼中, 你可以把Lambda 表達式作為第二個參數傳給filter 方法, 因為它這里需要Predicate<T>,而這是一個函數式接口。

函數式接口

Predicate僅僅定義了一個抽象方法

public interface Predicate<T>{boolean test (T t); }

一言以蔽之,函數式接口就是只定義一個抽象方法的接口。

Java API中的一些其他函數式接口,

//java.util.Comparator public interface Comparator<T> {int compare(T o1, T o2); }//java.lang.Runnable public interface Runnable{void run(); }//java.awt.event.ActionListener public interface ActionListener extends EventListener{void actionPerformed(ActionEvent e); }//java.util.concurrent.Callable public interface Callable<V>{V call(); }//java.security.PrivilegedAction public interface PrivilegedAction<V>{V run(); }

用函數式接口可以干什么呢?Lambda表達式允許你直接以內聯的形式為函數式接口的抽象方法提供實現,并把整個表達式作為函數式接口的實例(具體說來,是函數式接口一個具體實現的實例)。

你用匿名內部類也可以完成同樣的事情,只不過比較笨拙:需要提供一個實現,然后再直接內聯將它實例化。下面的代碼是有效的,因為Runnable是一個只定義了一個抽象方法run的函數式接口

Runnable r1 = () -> System.out.println("Hello World 1"); Runnable r2 = new Runnable(){public void run(){System.out.println("Hello World 2");} };public static void process(Runnable r){r.run(); }process(r1); process(r2);process(() -> System.out.println("Hello World 3"));

函數描述符

函數式接口的抽象方法的簽名基本上就是Lambda表達式的簽名。我們將這種抽象方法叫作函數描述符

為什么只有在需要函數式接口的時候才可以傳遞Lambda呢?語言設計者選擇了現在這種方式,因為這種方式自然且能避免語言變得更復雜。

@FunctionalInterface
如果你去看看新的Java API,會發現函數式接口帶有@FunctionalInterface的標注。這個標注用于表示該接口會設計成一個函數式接口。

如果你用@FunctionalInterface定義了一個接口,而它卻不是函數式接口的話,編譯器將返回一個提示原因的錯誤。

例如,錯誤消息可能是“Multiple non-overriding abstract methods found in interface Foo”,表明存在多個抽象方法。

請注意,@FunctionalInterface不是必需的,但對于為此設計的接口而言,使用它是比較好的做法。它就像是@Override標注表示方法被重寫了。

把Lambda 付諸實踐:環繞執行模式

資源處理(例如處理文件或數據庫)時一個常見的模式就是打開一個資源,做一些處理,然后關閉資源。

這個設置和清理階段總是很類似,并且會圍繞著執行處理的那些重要代碼。這就是所謂的環繞執行(execute around)模式

public static String processFile() throws IOException {try (BufferedReader br = new BufferedReader(new FileReader("data.txt"))) {return br.readLine();//這就是做有用工作的那行代碼} }

把processFile的行為參數化。需要一種方法把行為傳遞給processFile,以便它可以利用BufferedReader執行不同的行為。

第1步:記得行為參數化

public static String processFile() throws IOException {try (BufferedReader br = new BufferedReader(new FileReader("data.txt"))) {return br.readLine();//這就是做有用工作的那行代碼} }

轉化成

String result = processFile((BufferedReader br) -> br.readLine());

第2步:使用函數式接口來傳遞行為

@FunctionalInterface public interface BufferedReaderProcessor {String process(BufferedReader b) throws IOException; }

現在你就可以把這個接口作為新的processFile方法的參數了:

public static String processFile(BufferedReaderProcessor p) throws IOException {}

第3步:執行一個行為

public static String processFile(BufferedReaderProcessor p) throws IOException {try (BufferedReader br = new BufferedReader(new FileReader("data.txt"))) {return p.process(br);} }

第4步:傳遞Lambda

現在你就可以通過傳遞不同的Lambda重用processFile方法,并以不同的方式處理文件了。

處理一行:

String oneLine = processFile((BufferedReader br) -> br.readLine());

處理兩行:

String twoLines = processFile((BufferedReader br) -> br.readLine() + br.readLine());

使用函數式接口

函數式接口的抽象方法的簽名稱為函數描述符。所以為了應用不同的Lambda表達式,你需要一套能夠描述常見函數描述符的函數式接口。

Predicate

java.util.function.Predicate<T>接口定義了一個名叫test的抽象方法,它接受泛型T對象,并返回一個boolean。

@FunctionalInterface public interface Predicate<T>{boolean test(T t); }public static <T> List<T> filter(List<T> list, Predicate<T> p) {List<T> results = new ArrayList<>();for(T s: list){if(p.test(s)){results.add(s);}}return results; }Predicate<String> nonEmptyStringPredicate = (String s) -> !s.isEmpty(); List<String> nonEmpty = filter(listOfStrings, nonEmptyStringPredicate);

Consumer

java.util.function.Consumer定義了一個名叫accept的抽象方法,它接受泛型T的對象,沒有返回(void)。你如果需要訪問類型T的對象,并對其執行某些操作,就可以使用這個接口。比如,你可以用它來創建一個forEach方法,接受一個Integers的列表,并對其中每個元素執行操作。

@FunctionalInterface public interface Consummer<T> {void accept(T t); }public static <T> void forEach(List<T> list, Consumer<T> c) {for(T i : list) c.accept(i); }forEach(Arrays.asList(1,2,3,4,5,6,7), (Integer i)->System.out.println(i));

Function

java.util.function.Function<T, R>接口定義了一個叫作apply的方法,它接受一個泛型T的對象,并返回一個泛型R的對象。如果你需要定義一個Lambda,將輸入對象的信息映射到輸出,就可以使用這個接口(比如提取蘋果的重量,或把字符串映射為它的長度)

@FunctionalInterface public interface Function<T, R> {R apply(T t); }public static <T,R> List<R> map(List<T> list, Function<T,R> f){List<R> result = new ArrayList<>();for(T s : list) {result.add(f.apply(s));}return result; }List<Integer> list2 = map(Arrays.asList("","1234","asd"),(String s)->s.length()); System.out.println(list2);

原始類型特化

泛型(比如Consumer<T>中的T)只能綁定到引用類型。這是由泛型內部的實現方式造成的。因此,在Java里有一個將原始類型轉換為對應的引用類型的機制。這個機制叫作裝箱(boxing)。相反的操作,也就是將引用類型轉換為對應的原始類型,叫作拆箱(unboxing)。

但這在性能方面是要付出代價的。裝箱后的值本質上就是把原始類型包裹起來,并保存在堆里。因此,裝箱后的值需要更多的內存,并需要額外的內存搜索來獲取被包裹的原始值。

Java 8 提供特殊的函數式接口,以便在輸入和輸出都是原始類型避免自動裝箱操作

public interface IntPredicate{boolean test(int t); }//無裝箱 IntPredicate evenNumbers = (int i) -> i % 2 == 0; evenNumbers.test(1000);//裝箱 Predicate<Integer> oddNumbers = (Integer i) -> i % 2 == 1; oddNumbers.test(1000);

Java 8 中的常用函數式接口

//助記//喂,消費者,生產者,我們一起玩(fun)吧 Predicate,Consumer,Supplier,Function//數學 一元符,二元符 UnaryOperator,BinaryOperator//(喂,消費者,生產者)* 2 BiPredicate,BiConsumer,BiFunction 函數式接口函數描述符原始類型特化
Predicate<T>T->booleanIntPredicate, LongPredicate, DoublePredicate
Consumer<T>T->voidIntConsumer, LongConsumer, DoubleConsumer
Function<T,R>T->RIntFunction<R>, IntToDoubleFunction, IntToLongFunction, LongFunction<R>, LongToDoubleFunction, LongToIntFunction, DoubleFunction<R>, ToIntFunction<T>, ToDoubleFunction<T>, ToLongFunction<T>
Supplier<T,R>()->TBooleanSupplier, IntSupplier, LongSupplier, DoubleSupplier
UnaryOperator<T,R>T->TIntUnaryOperator, LongUnaryOperator, DoubleUnaryOperator
BinaryOperator<T,R>(T,T)->TIntBinaryOperator, LongBinaryOperator, DoubleBinaryOperator
BiPredicate<L,R>(L,R)->boolean-
BiConsumer<T,U>(T,U)->voidObjIntConsumer<T,R>, ObjLongConsumer<T,R>, ObjDoubleConsumer<T,R>
BiFunction<T,U,R>(T,U)->RToIntBiFunction<T,U>, ToLongBiFunction<T,U>, ToDoubleBiFunction<T,U>

Lambda示例

使用案例Lambda示例對應的函數式接口
布爾表達式(List<String> list) -> list.isEmpty()Predicate<List<String>>
創建對象() -> new Apple(10)Supplier<Apple>
消費一個對象(Apple a) -> { System.out.println(a.getWeight()); }Consumer<Apple>
從一個對象中選擇/抽取(String s) -> s.length()Function<String, Integer>或 ToIntFunction<String>
組合兩個值(int a, int b) -> a * bIntBinaryOperator
比較兩個對象(Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight())Comparator或 BiFunction<Apple, Apple, Integer> 或 ToIntBiFunction<Apple, Apple>

異常

任何函數式接口都不允許拋出受檢異常(checked exception)。如果你需要Lambda表達式來拋出異常,有兩種辦法:

  • 定義一個自己的函數式接口,并聲明受檢異常,
  • 把Lambda包在一個try/catch塊中
  • @FunctionalInterface public interface BufferedReaderProcessor {String process(BufferedReader b) throws IOException; }BufferedReaderProcessor p = (BufferedReader br) -> br.readLine(); Function<BufferedReader, String> f = (BufferedReader b) -> {try {return b.readLine();}catch(IOException e) {throw new RuntimeException(e);} };

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

    類型檢查

    Lambda的類型是從使用Lambda的上下文推斷出來的。上下文(比如,接受它傳遞的方法的參數,或接受它的值的局部變量)中Lambda表達式需要的類型稱為目標類型。

    • 首先,你要找出filter方法的聲明。
    • 第二,要求它是Predicate(目標類型)對象的第二個正式參數。
    • 第三,Predicate是一個函數式接口,定義了一個叫作test的抽象方法。
    • 第四,test方法描述了一個函數描述符,它可以接受一個Apple,并返回一個boolean。
    • 最后,filter的任何實際參數都必須匹配這個要求。

    同樣的Lambda,不同的函數式接口

    Comparator<Apple> c1 = (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());ToIntBiFunction<Apple, Apple> c2 = (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());BiFunction<Apple, Apple, Integer> c3 = (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());

    特殊的void兼容規則

    如果一個Lambda的主體是一個語句表達式, 它就和一個返回void的函數描述符兼容(當然需要參數列表也兼容)。例如,以下兩行都是合法的,盡管List的add方法返回了一個boolean,而不是Consumer上下文(T -> void)所要求的void:

    // Predicate返回了一個boolean Predicate<String> p = s -> list.add(s); // Consumer返回了一個void Consumer<String> b = s -> list.add(s);

    類型檢查——為什么下面的代碼不能編譯呢?
    你該如何解決這個問題呢?

    Object o = () -> {System.out.println("Tricky example"); };

    答案:Lambda表達式的上下文是Object(目標類型)。但Object不是一個函數式接口
    為了解決這個問題,你可以把目標類型改成Runnable,它的函數描述符是() -> void:

    Runnable r = () -> {System.out.println("Tricky example"); };

    類型推斷

    Java編譯器會從上下文(目標類型)推斷出用什么函數式接口來配合Lambda表達式,這意味著它也可以推斷出適合Lambda的簽名,因為函數描述符可以通過目標類型來得到。這樣做的好處在于,編譯器可以了解Lambda表達式的參數類型,這樣就可以在Lambda語法中省去標注參數類型。

    List<Apple> greenApples = filter(inventory, a -> "green".equals(a.getColor()));

    Lambda表達式有多個參數,代碼可讀性的好處就更為明顯。例如,你可以這樣來創建一個Comparator對象

    Comparator<Apple> c = (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());//有類型推斷 Comparator<Apple> c = (a1, a2) -> a1.getWeight().compareTo(a2.getWeight());

    使用局部變量

    不鼓勵使用外部變量

    Lambda表達式也允許使用自由變量(不是參數,而是在外層作用域中定義的變量),就像匿名類一樣。 它們被稱作捕獲Lambda

    int portNumber = 1337; Runnable r = () -> System.out.println(portNumber); portNumber = 31337;

    錯誤: Lambda表達式引用的局部變量必須是最終的(final
    或事實上最終的


    為什么局部變量有這些限制?

  • 實例變量和局部變量背后的實現有一個關鍵不同。實例變量都存儲在中,而局部變量則保存在上。如果Lambda可以直接訪問局部變量,而且Lambda是在一個線程中使用的,則使用Lambda的線程,可能會在分配該變量的線程將這個變量收回之后,去訪問該變量。因此,Java在訪問自由局部變量時,實際上是在訪問它的副本,而不是訪問原始變量。如果局部變量僅僅賦值一次那就沒有什么區別了——因此就有了這個限制。

  • 這一限制不鼓勵你使用改變外部變量的典型命令式編程模式。

  • 方法引用

    方法引用的基本思想是,如果一個Lambda代表的只是“直接調用這個方法”,那最好還是用名稱來調用它,而不是去描述如何調用它。

    事實上,方法引用就是讓你根據已有的方法實現來創建
    Lambda表達式。

    但是,顯式地指明方法的名稱,你的代碼的可讀性會更好

    PS. I don’t think so.

    它是如何工作的呢?當你需要使用方法引用時,目標引用放在分隔符::前,方法的名稱放在后面。例如,Apple::getWeight就是引用了Apple類中定義的方法getWeight。

    先前:

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

    之后(使用方法引用和java.util.Comparator.comparing):

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

    管中窺豹

    Lambda及其等效方法引用的例子

    Lambda等效的方法引用
    (Apple a) -> a.getWeight()Apple::getWeight
    () -> Thread.currentThread().dumpStack()Thread.currentThread()::dumpStack
    (str, i) -> str.substring(i)String::substring
    (String s) -> System.out.println(s)System.out::println

    你可以把方法引用看作針對僅僅涉及單一方法的Lambda的語法糖,因為你表達同樣的事情時要寫的代碼更少了。

    如何構建方法引用

    方法引用主要有三類。

  • 指向靜態方法的方法引用(例如Integer的parseInt方法,寫作Integer::parseInt)

  • 指向任意類型實例方法的方法引用(例如String的length方法,寫作String::length)。//(String s) -> s.toUppeCase()

  • 指向現有對象的實例方法的方法引用(假設你有一個局部變量expensiveTransaction用于存放Transaction類型的對象,它支持實例方法getValue,那么你就可以寫expensiveTransaction::getValue)//()->expensiveTransaction.getValue()

  • 例子

    第二種

    List<String> str = Arrays.asList("a","b","A","B"); str.sort((s1, s2) -> s1.compareToIgnoreCase(s2));List<String> str = Arrays.asList("a","b","A","B"); str.sort(String::compareToIgnoreCase);

    第二種

    Function<String, Integer> stringToInteger = (String s) -> Integer.parseInt(s);Function<String, Integer> stringToInteger = Integer::parseInt;

    第二種

    BiPredicate<List<String>, String> contains = (list, element) -> list.contains(element);BiPredicate<List<String>, String> contains = List::contains;

    構造函數引用

    無參構造函數的

    Supplier<Apple> c1 = Apple::new; Apple a1 = c1.get();

    等同

    Supplier<Apple> c1 = () -> new Apple(); Apple a1 = c1.get();

    若構造函數是Apple(Integer weight)

    Function<Integer, Apple> c2 = Apple::new; Apple a2 = c2.apply(110);

    等同

    Function<Integer, Apple> c2 = (weight) -> new Apple(weight); Apple a2 = c2.apply(110);

    若構造函數是Apple(String color, Integer weight)

    BiFunction<String, Integer, Apple> c3 = Apple::new; Apple c3 = c3.apply("green", 110);

    等同

    BiFunction<String, Integer, Apple> c3 = (color, weight) -> new Apple(color, weight); Apple c3 = c3.apply("green", 110);

    運用實例

    List<Integer> weights = Arrays.asList(7, 3, 4, 10); List<Apple> apples = map(weights, Apple::new);public static List<Apple> map(List<Integer> list,Function<Integer, Apple> f){List<Apple> result = new ArrayList<>();for(Integer e: list){result.add(f.apply(e));}return result; }
    static Map<String, Function<Integer, Fruit>> map = new HashMap<>();static {map.put("apple", Apple::new);map.put("orange", Orange::new); // etc... }public static Fruit giveMeFruit(String fruit, Integer weight){return map.get(fruit.toLowerCase()).apply(weight); }

    構造函數引用

    你已經看到了如何將有零個、一個、兩個參數的構造函數轉變為構造函數引用。那要怎么樣才能對具有三個參數的構造函數,比如Color(int, int, int),使用構造函數引用呢?

    構造函數引用的語法是ClassName::new,那么在這個例子里面就是Color::new。但是你需要與構造函數引用的簽名匹配的函數式接口。但是語言本身并沒有提供這樣的函數式接口,你可以自己創建一個:

    public interface TriFunction<T, U, V, R>{R apply(T t, U u, V v); }

    現在你可以像下面這樣使用構造函數引用了:

    TriFunction<Integer, Integer, Integer, Color> colorFactory = Color::new;

    Lambda和方法引用實戰

    以排序為例

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

    第1步:傳遞代碼

    void sort(Comparator<? super E> c)public class AppleComparator implements Comparator<Apple> {public int compare(Apple a1, Apple a2){return a1.getWeight().compareTo(a2.getWeight());} }inventory.sort(new AppleComparator());

    第2步:使用匿名類

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

    第3步:使用Lambda表達式

    inventory.sort((Apple a1, Apple a2)-> a1.getWeight().compareTo(a2.getWeight()));//進一步簡化 inventory.sort((a1, a2) -> a1.getWeight().compareTo(a2.getWeight()));//現在你可以把代碼再改得緊湊一點了:Comparator<Apple> c = Comparator.comparing((Apple a) -> a.getWeight());import static java.util.Comparator.comparing; inventory.sort(comparing((a) -> a.getWeight()));

    第4步:使用方法引用

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

    復合Lambda表達式的有用的方法

    比較器復合

    逆序

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

    比較器鏈

    inventory.sort(comparing(Apple::getWeight).reversed().thenComparing(Apple::getCountry)); //兩個蘋果一樣重時,進一步按國家排序

    謂詞復合

    謂詞接口包括三個方法: negate、 and和or,讓你可以重用已有的Predicate來創建更復雜的謂詞。

    //產生現有Predicate對象redApple的非 Predicate<Apple> notRedApple = redApple.negate();Predicate<Apple> redAndHeavyApple = redApple.and(a -> a.getWeight() > 150);Predicate<Apple> redAndHeavyAppleOrGreen = redApple.and(a -> a.getWeight() > 150).or(a -> "green".equals(a.getColor()));

    函數復合

    最后,你還可以把Function接口所代表的Lambda表達式復合起來。 Function接口為此配了andThen和compose兩個默認方法,它們都會返回Function的一個實例。

    Function<Integer, Integer> f = x -> x + 1; Function<Integer, Integer> g = x -> x * 2; Function<Integer, Integer> h = f.andThen(g); int result = h.apply(1);//x=1,結果是4Function<Integer, Integer> f = x -> x + 1; Function<Integer, Integer> g = x -> x * 2; Function<Integer, Integer> h = f.compose(g); int result = h.apply(1);//x=1,結果是3


    做文本轉換 為例

    public class Letter{public static String addHeader(String text){return "From Raoul, Mario and Alan: " + text;}public static String addFooter(String text){return text + " Kind regards";}public static String checkSpelling(String text){return text.replaceAll("labda", "lambda");} }

    函數復合

    Function<String, String> addHeader = Letter::addHeader; Function<String, String> transformationPipeline = addHeader.andThen(Letter::checkSpelling).andThen(Letter::addFooter);

    數學中類似的思想

    積分

    在這個例子里,函數f是一條直線,因此你很容易通過梯形方法(畫幾個三角形)來算出面積:

    1/2 × ((3 + 10) + (7 + 10)) × (7 – 3) = 60

    運用Lambda表達式

    integrate((double x) -> x + 10, 3, 7)public double integrate(DoubleFunction<Double> f, double a, double b) {return (f.apply(a) + f.apply(b)) * (b-a) / 2.0; }

    小結

    • Lambda表達式可以理解為一種匿名函數:它沒有名稱,但有參數列表、函數主體、返回類型,可能還有一個可以拋出的異常的列表。
    • Lambda表達式讓你可以簡潔地傳遞代碼。
    • 函數式接口就是僅僅聲明了一個抽象方法的接口。
    • 只有在接受函數式接口的地方才可以使用Lambda表達式。
    • Lambda表達式允許你直接內聯,為函數式接口的抽象方法提供實現,并且將整個表達式作為函數式接口的一個實例。
    • Java 8自帶一些常用的函數式接口,放在java.util.function包里,包括Predicate<T>、Function<T,R>、Supplier<T>、Consumer<T>和BinaryOperator<T>,
    • 為了避免裝箱操作,對Predicate<T>和Function<T, R>等通用函數式接口的原始類型特化:IntPredicate、IntToLongFunction等。
    • 環繞執行模式(即在方法所必需的代碼中間,你需要執行點兒什么操作,比如資源分配和清理)可以配合Lambda提高靈活性和可重用性。
    • Lambda表達式所需要代表的類型稱為目標類型。
    • 方法引用讓你重復使用現有的方法實現并直接傳遞它們。
    • Comparator、Predicate和Function等函數式接口都有幾個可以用來結合Lambda表達式的默認方法。

    總結

    以上是生活随笔為你收集整理的《Java8实战》笔记(03):Lambda表达式的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。