Java 基礎(Lambda表示式 和 函式式 Functional 介面)
阿新 • • 發佈:2021-11-29
Lambda表示式
函式式 Functional 介面
- 只包含一個抽象方法的介面,稱為函式式介面。
- 你可以通過 Lambda 表示式來建立該介面的物件。(若 Lambda 表示式丟擲一個受檢異常(即:非執行時異常),那麼該異常需要在目標介面的抽象方法上進行宣告)。
- 我們可以在一個介面上使用 @FunctionalInterface 註解,這樣做可以檢查它是否是一個函式式介面。同時 javadoc 也會包含一條宣告,說明這個介面是一個函式式介面。
- 在 java.util.function 包下定義了Java 8的豐富的函式式介面
- Java 從誕生日起就是一直倡導 “一切皆物件”,在Java裡面面向物件(OOP)程式設計是一切。但是隨著python、scala等語言的興起和新技術的挑戰,Java不得不做出調整以便支援更加廣泛的技術要求,也即 java 不但可以支援OOP還可以支援OOF(面向函式程式設計)
- 在函數語言程式設計語言當中,函式被當做一等公民對待。在將函式作為一等公民的程式語言中,Lambda表示式的型別是函式。但是在Java8中,有所不同。在Java8中,Lambda表示式是物件,而不是函式,它們必須依附於一類特別的物件型別——函式式介面。
- 簡單的說,在Java8中,Lambda表示式就是一個函式式介面的例項。這就是Lambda表示式和函式式介面的關係。也就是說,只要一個物件是函式式介面的例項,那麼該物件就可以用Lambda表示式來表示。
- 所以以前用匿名實現類表示的現在都可以用Lambda表示式來寫。
Java 內建四大核心函式式介面
其他介面
LambdaTest.java
packagecom.klvchen.java1; import org.junit.Test; import java.util.Comparator; public class LambdaTest { @Test public void test1(){ Runnable r1 = new Runnable() { @Override public void run() { System.out.println("我愛北京天安門"); } }; r1.run(); System.out.println("**********************************"); Runnable r2 = () -> System.out.println("我愛北京故宮"); r2.run(); } @Test public void test2(){ Comparator<Integer> com1 = new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return Integer.compare(o1, o2); } }; int compare1 = com1.compare(12, 21); System.out.println(compare1); System.out.println("***************************************"); Comparator<Integer> com2 = (o1, o2) -> Integer.compare(o1,o2); int compare2 = com2.compare(32, 21); System.out.println(compare2); System.out.println("***************************************"); //方法引用 Comparator<Integer> com3 = Integer :: compare; int compare3 = com3.compare(32, 21); System.out.println(compare3); } }
LambdaTest1.java
package com.klvchen.java1; import org.junit.Test; import java.util.ArrayList; import java.util.Comparator; import java.util.function.Consumer; /* Lambda表示式的使用 1.舉例: (o1,o2) -> Integer.compare(o1,o2); 2.格式: ->左邊: Lambda形參列表的引數型別可以省略(型別推斷);如果Lambda形參列表只有一個引數,其一對()也可以省略 ->右邊: Lambda體應該使用一對{}包裹;如果Lambda體只有一條執行語句(可能是return語句),可以省略這一對{}和return關鍵字 3.Lambda 表示式的使用:(分為6種情況) 4.Lambda 表示式的本質:作為介面的例項 5.如果一個介面中,只聲明瞭一個抽象方法,則此介面就稱為函式式介面 6.所以以前用匿名實現類表示的現在都可以用Lambda表示式來寫。 */ public class LambdaTest1 { // 語法格式一:無參,無返回值 @Test public void test1(){ Runnable r1 = new Runnable() { @Override public void run() { System.out.println("我愛北京天安門"); } }; r1.run(); System.out.println("*****************************"); Runnable r2 = () -> System.out.println("我愛北京故宮"); r2.run(); } //語法格式二:Lambda需要一個引數,但是沒有返回值。 @Test public void test2(){ Consumer<String> con = new Consumer<String>() { @Override public void accept(String s) { System.out.println(s); } }; con.accept("謊言和誓言的區別是什麼?"); System.out.println("*****************************"); Consumer<String> con1 = (String s) -> { System.out.println(s); }; con1.accept("一個是聽得人當真了,一個是說的人當真了"); } //語法格式三:資料型別可以省略,因為可由編譯器推斷得出,稱為"型別推斷" @Test public void test3(){ Consumer<String> con1 = (String s) -> { System.out.println(s); }; con1.accept("一個是聽得人當真了,一個是說的人當真了"); System.out.println("*****************************"); Consumer<String> con2 = (s) ->{ System.out.println(s); }; con2.accept("一個是聽得人當真了,一個是說的人當真了"); } @Test public void test4(){ ArrayList<String> list = new ArrayList<>();//型別推斷 int[] arr = {1, 2, 3};//型別推斷 } //語法格式四: Lambda若只需要一個引數時,引數的小括號可以省略 public void test5(){ Consumer<String> con1 = (s) -> { System.out.println(s); }; con1.accept("一個是聽得人當真了,一個是說的人當真了"); System.out.println("*****************************"); Consumer<String> con2 = s -> { System.out.println(s); }; con2.accept("一個是聽得人當真了,一個是說的人當真了"); } //語法格式五:Lambda需要兩個或以上的引數,多條執行語句,並且可以有返回值 @Test public void test6(){ Comparator<Integer> com1 = new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { System.out.println(o1); System.out.println(o2); return o1.compareTo(o2); } }; System.out.println(com1.compare(12,21)); System.out.println("*****************************"); Comparator<Integer> com2 = (o1,o2) -> { System.out.println(o1); System.out.println(o2); return o1.compareTo(o2); }; System.out.println(com2.compare(12,6)); } //語法格式六:當Lambda體只有一條語句時,return 與大括號若有,都可以省略 @Test public void test7(){ Comparator<Integer> com1 = (o1, o2) -> { return o1.compareTo(o2); }; System.out.println(com1.compare(12, 6)); System.out.println("******************************************************"); Comparator<Integer> com2 = (o1, o2) -> o1.compareTo(o2); System.out.println(com2.compare(12, 21)); } @Test public void test8(){ Consumer<String> con1 = s -> { System.out.println(s); }; con1.accept("一個是聽得人當真了,一個是說的人當真了"); System.out.println("******************************************************"); Consumer<String> con2 = s -> System.out.println(s); con2.accept("一個是聽得人當真了,一個是說的人當真了"); } }
LambdaTest2.java
package com.klvchen.java1; /* java內建的4大核心函最式介面 消費型介面 Consumer<T> void accept(T t) 供給型介面 Supplier<T> T get() 函式型介面 Function<T,R> R apply(T t) 斷定型介面 Predicate<T> booLean test(T t) */ import org.junit.Test; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.function.Consumer; import java.util.function.Predicate; public class LambdaTest2 { @Test public void test1(){ happyTime(500, new Consumer<Double>() { @Override public void accept(Double aDouble) { System.out.println("學習太累了,去天上人間買了瓶礦泉水,價格為: " + aDouble); } }); System.out.println("**************************************************"); happyTime(400, money -> System.out.println("學習太累了,去天上人間買了瓶礦泉水,價格為: " + money)); } public void happyTime(double money, Consumer<Double> con) { con.accept(money); } @Test public void test2(){ List<String> list = Arrays.asList("北京","南京","天津","東京","西京","普京"); List<String> filterStrs = filterString(list, new Predicate<String>() { @Override public boolean test(String s) { return s.contains("京"); } }); System.out.println(filterStrs); List<String> filterStrs1 = filterString(list, s -> s.contains("京")); System.out.println(filterStrs1); } //據給定的規剩,過濾集合中的字串。此規則由Predicate的方法決定 public List<String> filterString(List<String> list, Predicate<String> pre){ ArrayList<String> filterList = new ArrayList<>(); for (String s : list) { if (pre.test(s)){ filterList.add(s); } } return filterList; } }