java中lambda的使用

lambda表達式:

思想轉變:

函數式編程思想:不在乎過程的方式,不在乎對象是那個,只在乎返回結果(重結果,輕過程)

面向對象思想:找一個對象,去做事情(萬物皆對象)

轉變過程:

以多線程爲例:

使用普通方法進行多線程操作

爲了獲取Runnable接口的實現對象,爲該接口定義一個實現類`RunnableImpl,設置線程任務

public class RunnableImpl implements Runnable {
	@Override
	public void run() {
		System.out.println("多線程任務執行!");
	}
}

然後創建該實現類的對象作爲Thread類的構造參數:

public class Demo03ThreadInitParam {
	public static void main(String[] args) {
		Runnable task = new RunnableImpl();
		new Thread(task).start();
	}
}

使用匿名內部類

這個RunnableImpl類只是爲了實現Runnable接口而存在的,而且僅被使用了唯一一次,所以使用匿名內部類的語法即可省去該類的單獨定義,即匿名內部類:

public class Demo04ThreadNameless {
	public static void main(String[] args) {
		new Thread(new Runnable() {
			@Override
			public void run() {
				System.out.println("多線程任務執行!");
			}
		}).start();
	}
}

使用lambda表達式

public class Demo04ThreadNameless {
	public static void main(String[] args) {
		new Thread(() -> System.out.println("多線程任務執行!")).start();
	}
}

你會發現使用了lambda表達式的書寫代碼簡約而不簡單

Lambda標準格式

Lambda省去面向對象的條條框框,格式由3個部分組成:

  • 一些參數
  • 一個箭頭
  • 一段代碼

Lambda表達式的標準格式爲:

(參數類型 參數名稱) -> { 代碼語句 }

格式說明:

  • 小括號內的語法與傳統方法參數列表一致:無參數則留空;多個參數則用逗號分隔。
  • ->是新引入的語法格式,代表指向動作。
  • 大括號內的語法與傳統方法體要求基本一致。
  • lambda特點:延遲執行。

Lambda的使用前提

Lambda的語法非常簡潔,完全沒有面向對象複雜的束縛。但是使用時有幾個問題需要特別注意:

  1. 使用Lambda必須具有接口,且要求接口中有且僅有一個抽象方法
    無論是JDK內置的RunnableComparator接口還是自定義的接口,只有當接口中的抽象方法存在且唯一時,纔可以使用Lambda。
  2. 使用Lambda必須具有上下文推斷
    也就是方法的參數或局部變量類型必須爲Lambda對應的接口類型,才能使用Lambda作爲該接口的實例。

備註:有且僅有一個抽象方法的接口,稱爲“函數式接口”。

@FunctionalInterface註解

與 @Override 註解的作用類似,Java 8中專門爲函數式接口引入了一個新的註解: @FunctionalInterface 。該注
解可用於一個接口的定義上:

一旦使用該註解來定義接口,編譯器將會強制檢查該接口是否確實有且僅有一個抽象方法,否則將會報錯。需要注意的是,即使不使用該註解,只要滿足函數式接口的定義,這仍然是一個函數式接口,使用起來都一樣。

@FunctionalInterface
public interface MyFunctionalInterface {
    void myMethod();
}

常用函數式接口

Supplier接口

java.util.function.Supplier 接口僅包含一個無參的方法: T get() 。由於這是一個函數式接口,這也就意味着對應的Lambda表達式需要“對外提供”一個符合泛型類型的對象數據。

作用:生產型接口,指定接口的泛型是什麼,就生產什麼類型的數據

Consumer接口

java.util.function.Consumer 接口則正好與Supplier接口相反,它不是生產一個數據,而是消費一個數據,
其數據類型由泛型決定。
抽象方法:accept
Consumer 接口中包含抽象方法 void accept(T t) ,意爲消費一個指定泛型的數據。

作用:消費性接口,泛型執行什麼類型,就可以使用accept消費什麼類型的數據

默認方法:andThen
如果一個方法的參數和返回值全都是 Consumer 類型,那麼就可以實現效果:消費數據的時候,首先做一個操作,
然後再做一個操作,實現組合。而這個方法就是 Consumer 接口中的default方法 andThen 。下面是JDK的源代碼:

Consummer<String> con1;
Consummer<String> con2;
String s="hello";
con1.accept(s);
con2.accept(s);
con1.andThen(con2).accept(s);

Predicate接口

作用:對某種類型的數據進行判斷,從而得到一個boolean值結果。
java.util.function.Predicate 接口。
抽象方法:test
Predicate 接口中包含一個抽象方法: boolean test(T t) 。用於條件判斷的場景:

默認方法:and ,有false則false
既然是條件判斷,就會存在與、或、非三種常見的邏輯關係。其中將兩個 Predicate 條件使用“與”邏輯連接起來實
現“並且”的效果時,可以使用default方法 and 。

p1.and(p2).test(S)
p1.test(s)&&p2.test(s)

默認方法:or 有true則true
與 and 的“與”類似,默認方法 or 實現邏輯關係中的“或”。

默認方法:negate 有true則false,有false則true
“與”、“或”已經瞭解了,剩下的“非”(取反)也會簡單。

Function接口

作用:接口用來根據一個類型的數據得到另一個類型的數據,前者稱爲前置條件,後者稱爲後置條件。

java.util.function.Function<T,R>
抽象方法:apply
Function 接口中最主要的抽象方法爲: R apply(T t) ,根據類型T的參數獲取類型R的結果。
使用的場景例如:將 String 類型轉換爲 Integer 類型。

默認方法:andThen
Function 接口中有一個默認的 andThen 方法,用來進行組合操作

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章