lambda-1-lambda簡介

lambda用法

1、函數式接口

  • 函數式接口用@FunctionalInterface註解標註的接口類,lambda必須和函數式接口的抽象函數描述一樣的參數類型。
  • 一個接口類只包含一個抽象方法,這個接口爲函數式接口。(jdk8之後可以再接口類中聲明其他方法,需要在方法前面添加default,即默認方法。)
  • 關於函數式接口第一個條件:
    • 如果一個接口只有一個抽象方法,那麼這個接口是一個函數式接口;
    • 如果我們在某個接口上聲明瞭FunctionalInterface接口,如果不滿足函數式 接口的要求,則會報錯;
    • 如果某個接口只有一個抽象方法,但是我們並沒有給該接口聲明FunctionalInterface註解,這個時候,編譯器還是會將此接口視爲函數式接口。
@FunctionalInterface
interface Converter<F, T> { 
	T convert(F from);
}
  • 可以使用lambda接口實現Converter接口
Converter<String, Integer> converter = (param) -> Integer.valueOf(param);
Integer result = converter.convert("101");
System.out.println(result);
  • 如Thread線程啓動
new Thread(() -> System.out.println("hello lambda)).start();

2、方法引用

  • 方法引用是lambda表達式的一個簡化方法。語法結構爲:
ObjectRef::methodName

2.1、靜態方法引用

public class ReferenceTest {
	public static void main(String[] args) {
		Converter<String, Integer> converter = ReferenceTest::String2Int;
		System.out.println(converter.convert("110"));
	}

	static Integer String2Int(String from) {
		return Integer.valueOf(from);
	}
}

2.2、實例方法引用

Helper helper = new Helper();
Converter<String, Integer> converter = helper::String2Int;
System.out.println(converter.convert("120"));

3、Stream

3.1、stream簡介

  • stream是一個可以對個序列中的元素執行各種計算操作的一個元素序列。下例爲鏈式調用將中間操作串聯起來。
    public static void main(String[] args) {
        List<String> list = new ArrayList<>(Arrays.asList("a1", "a2", "b1", "b2", "c1", "c2"));
        list.stream().filter(s -> s.startsWith("c")).map(String::toUpperCase).sorted().forEach(System.out::println);
    }
  • stream包含中間最終兩種形式的操作。
  • 中間操作返回值是一個stream,最終操作只能返回void或者一個非stream的結果。如filter,map,sorted是中間操作,forEach是最終操作。
  • 方法接口的行爲基本上都是無干擾和無狀態。無干擾爲該方法不修改stream的底層數據源;無狀態爲操作的執行是獨立的。

3.2、streams分類

  • 可以從不同的數據源創建stream。Collections、Lists、Sets這些類中新增stream()(順序stream)和parallelStream()(併發stream)方法。
  • List對象上調用stream()方法可以返回一個常規的對象流。
Arrays.asList("a1", "a2", "a3")
	.findFirst().ifPresent(System.out::println);
  • 可以直接用stream創建一個collection。使用Stream.of()方法就能從一組對象創建一個stream對象。
Stream.of("a1", "a2", "a3")
	.findFirst().ifPresent(System.out::println);
  • IntStream、LongStream、DoubleStream可以處理基本類型:int、long、double。可以用range()方法替換掉for循環。
IntStream.range(1, 4).forEach(System.out::println);
  • 基本類型流可以使用一些聚合方法
Arrays.stream(new int[] {1,2,3})
	.map(n -> 2 * n + 1)
	.average()
	.ifPresent(System.out::println);
)
  • 可以通過常規對象流的mapToInt()、mapToObj()等方法完成常規流與基本類型流的互相轉換。
IntStream.range(1, 4).mapToObj(i -> "a" + i).forEach(System.out::println);

3.3、處理順序

  • Laziness(延遲加載)是中間操作的一個重要特性。

4、爲何需要使用lambda表達式

  • 在java中,我們無法將函數作爲參數傳遞給一個方法,也無法聲明返回一個函數的方法;
  • 在JavaScript中,函數參數是一個函數返回值是另一個函數的情況是非常常見的。JavaScript是一種非常典型的函數式語言。
  • 同爲面嚮對象語言。

5、lambda表達式結構

5.1、lambda表達式基本結構

// 基本結構(一般結構)
(param1, param2, param3) -> {
}

// list使用
List<Integer> list = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
list.forEach(integer -> sout(integer));
list.forEach(System.out::println); // 方法引用 methodReference

6、lambda表達式作用

  • lambda表達式爲java添加了確實的函數式編程特性;
  • 在將函數作爲一等公民的語言當中,lambda表達式的類型是函數。**但在java中,lambda表達式是對象,**他們必須依附於一類特別的對象類型-函數式接口(functionalInterface)。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章