lambda表達式和函數式編程初探

一、函數式接口

理解FunctionalInterface(函數式接口)是學習Java8 Lambda表達式的基礎。

函數式接口的定義

  • 函數式接口是指在接口中只有一個抽象方法,可以使用 @FunctionalInterface註解來約束,有多個抽象方式就會報錯(但若抽象方法爲Object類中的方法,並不會報錯)
  • 函數式接口只能有一個抽象方法,所以在使用lambda表達式時,編譯器可以根據上下文直接找到接口中的方法。

函數式接口的用處

  • Java8中在java.util.function包下爲我們提供了很多的函數式接口,如下圖所示:

image

  • 提供的函數式接口中最主要的有四個,其他函數式接口都是根據這四個進行擴展的,以方便我們的開發。

四個函數式接口

我只講述下接口的抽象方法,至於默認方法和靜態方法大家可以自行了解。

  • 1、Consumer接口
    接受一個T類型參數,但並不返回值
@FunctionalInterface
public interface Consumer<T> {

    /**
     * 接受一個T類型的參數,但並不返回值
     * @param t 接收一個參數
     */
    void accept(T t);

}
  • 2、Function接口
    接收一個T類型參數,返回一個R類型結果

@FunctionalInterface
public interface Function<T, R> {

    /**
     * @param t 接收一個參數
     * @return 返回一個結果
     */
    R apply(T t);

    
}
  • 3、Supplier接口
    不接收參數,返回一個結果
@FunctionalInterface
public interface Supplier<T> {

    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}
  • 4、Predicate接口
    接收T類型參數並返回boolean
@FunctionalInterface
public interface Predicate<T> {

    /**
     * @param 接受一個T類型參數
     * @return 返回一個boolean值
     */
    boolean test(T t);
}

Lambda表達式

  • Java中Lambda表達式又被成爲“閉包”或“匿名方法”,其格式:(param1、param2) ‐>{函數體};

使用Lambda來演示Consumer接口

public class TestConsumer {
	
	public static void main(String[] args) {
		// 創建一個List集合,集合元素爲Integer
		List<Integer> list = Arrays.asList(1,2,3,4,5);
		System.out.println("-----------");
		// (i)就是Consumer中所傳遞的參數,而{System.out.println(i);}則是通過lambda創建的實例對象
		list.forEach((i) -> {System.out.println(i);});
		
		System.out.println("-----------");
		List<String> list2 = Arrays.asList("hello","lambda","hello lambda");
		list2.forEach((i) -> {System.out.println(i);});
		
	}
}

控制檯輸出結果如下:
-----------
1
2
3
4
5
-----------
hello
lambda
hello lambda

使用Lambda來演示Function接口

public class TestFunction {
	
	public static void main(String[] args) {
		
		// 創建一個TestFunction對象
		TestFunction test = new TestFunction();
		// (value) -> value * value 這部分就是通過lambda式創建出來的Function實例
		// 作用就是將傳進來的value進行平方,然後返回出去,這正好符合Function的定義,傳入一個參數,返回一個結果
		System.out.println("----------------");
		System.out.println(test.calculate((value) -> value * value,3));
		System.out.println("----------------");
		System.out.println(test.calculate((value) -> value * value,4));
		
	}
	
	/**
	 * @Description:  calculate用於計算一個函數值
	 * @param function 傳入一個Function函數作爲參數
	 * @param value 傳入一個Integer參數用來計算的
	 * @return
	 */
	public int calculate(Function<Integer, Integer> function,Integer value){
		return function.apply(value);
	}
	
}

控制檯輸出:
----------------
9
----------------
16

使用Lambda來演Supplier接口

public class TestSupplier {
	
	public static void main(String[] args) {
		TestSupplier test = new TestSupplier();
		// () -> Arrays.asList(1,2,3,5) 此處就是Supplier的一個實現
		// 不傳值獲取一個List集合,Supplier常用於工廠模式中
		List<Integer> result = test.getIntegerList(() -> Arrays.asList(1,2,3,5));
		System.out.println("---------------------");
		//遍歷集合 (value) -> System.out.println(value) 此處相當於一個Consumer集合
		result.forEach((value) -> System.out.println(value));
		System.out.println("---------------------");
		// 函數式接口實例還可以通過方法引用的方式來創建,這裏就不再進行詳解,我會在下篇文章進行介紹。
		result.forEach(System.out::println);
	}
	
	/**
	 * 
	 * @Description:  返回一個List
	 * @param supplier 傳入一個supplier函數
	 * @return
	 */
	public List<Integer> getIntegerList(Supplier<List<Integer>> supplier){
		return supplier.get();
	}
}

控制檯輸出:
---------------------
1
2
3
5
---------------------
1
2
3
5


使用Lambda來演示Predicate接口

public class TestPredicate {
	
	public static void main(String[] args) {
		TestPredicate test = new TestPredicate();
		// (value) -> value > 5 這部分其實就是lambda表達式生成的Predicate實例
		// 作用:判斷穿進去參數是否大於5,時則返回true,否則爲false
		System.out.println("---------------");
		System.out.println(test.testMethod((value) -> value > 5 ,5));
	}
	
	
	public boolean testMethod(Predicate<Integer> predicate,Integer value){
		return predicate.test(value);
	}
}

控制檯輸出爲:
---------------
false

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