Java 8中,Function,Consumer,Predicate,Supplier舉例 ,以及CompletableFuture使用

Function,Consumer,Predicate,Supplier這些接口有一個共性,就是都有一個@FunctionalInterface的註解, 有了這個註解,你就能夠自定義lamda表達式了.html

本文先介紹一些例子,而後自定義一個lamda表達式的接口.java

先看一下Function接口定義:app

    @FunctionalInterface    
    public interface Function<T, R>

接口接受兩個泛型類型<T, R>.異步

再看一下接口定義的方法(非靜態,非default), 支持lamda表達式的接口只容許定義一個抽象方法(@FunctionalInterface註解的接口,只容許定義一個抽象方法),只要記住這一點,你就不會弄混了..net

    R apply(T t);    
    /**
     * T 入參類型, t 輸入參數
     * R 返回值類型
     */

OK, 如今明確了, 該接口的lamda表達式應該是接受一個入參,最後要有一個返回值, 寫法應該是這樣的: (x) -> {return y;} 線程

若是你的lamda表達式很是簡單,只有一行,那麼你能夠不寫return, 不加花括號{}, 返回值後面能夠不加分號.code

下面就能夠寫example了, 寫一個簡單的, 再寫一個標準的.htm

    public void testFunction(){
                //簡單的,只有一行
		Function<Integer, String> function1 = (x) -> "test result: " + x;
		
		//標準的,有花括號, return, 分號.
		Function<String, String> function2 = (x) -> {
			return "after function1";
		};
		System.out.println(function1.apply(6));
		System.out.println(function1.andThen(function2).apply(6));
	}

OK, Function的例子寫完了,接下來寫其餘的,其實原理懂了,其餘的就都簡單了,而後就是熟能生巧了.blog

 

再看看Supplier的接口定義,這個接口定義比較簡單,我就都貼上來了接口

    @FunctionalInterface
    public interface Supplier<T> {

        /**
         * Gets a result.
         *
         * @return a result
         */
        T get();
    }

接口接受一個泛型<T>, 接口方法是一個無參數的方法, 有一個類型爲T的返回值. OK, 那麼接口的lamda表達式應該是這樣的: () -> { return something; }, 好,下面來寫一個example.

    public void testSupplier(){
                //簡寫
		Supplier<String> supplier1 = () -> "Test supplier";
		System.out.println(supplier1.get());
		
		//標準格式
		Supplier<Integer> supplier2 = () -> {
			return 20;
		};
		System.out.println(supplier2.get() instanceof Integer);
	}

到這裏你或許有一點疑惑, 這Supplier到底能用在哪啊? Java 8裏新增了一個異步線程的類,很牛逼,很強大的類: CompletableFuture, 裏面的不少方法的入參都用到的Supplier, 例如: supplyAsync方法. 本文暫時不介紹CompletableFuture.

 

接下來是Consumer, 咱們來看一下接口的定義:

    @FunctionalInterface
    public interface Consumer<T>

而後再看一下里面的抽象方法:

    void accept(T t);

如今瞭解了: 接口接受一個泛型<T>, 接口方法是入參類型爲T, 無返回值的方法, OK,下面開始寫example:

    public void testConsumer(){
		Consumer<String> consumer1 = (x) -> System.out.print(x);
		Consumer<String> consumer2 = (x) -> {
			System.out.println(" after consumer 1");
		};
		consumer1.andThen(consumer2).accept("test consumer1");
	}

 

接下來看一下Predicate接口

接口定義:

    @FunctionalInterface    
    public interface Predicate<T>

抽象方法:

    boolean test(T t);

接口接受一個泛型<T>, 接口方法的入參類型是T, 返回值是一個布爾值, OK, 下面寫example:

    public void testPredicate(){
		Predicate<String> predicate = (x) -> x.length() > 0;
		System.out.println(predicate.test("String"));
	}

Predicate接口在stream裏面用的比較多, 感興趣的能夠去看看stream, java 8 裏另外一個新的東西,很好玩.

 

 

 

到這裏基本明白這些lamda表達式的接口怎麼用了,接下來自定義一個支持lamda表達式的接口玩玩,

    @FunctionalInterface    
    public interface CustomLamda<T> {
    
    	T testCustomFunction(Consumer<T> cunsumer);
    	
    	/*若是把下面方法的註釋放開, 那麼接口就報錯了. 驗證了前面所說的:@FunctionalInterface註解的接口只容許         *有一個抽象方法
    	 */
        //T anErrorMethod();
    }

下面是實現:

    public void testCustomLamda(){
		Consumer<String> consumer = (x) -> {
			System.out.println("test" + x);
		};
		CustomLamda<String> customLamda = (x) -> {
			x.accept("6");
			return "6";
		};
		customLamda.testCustomFunction(consumer);
	}

CompletableFuture:

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
    int i = 1/0;
    return 100;

});

參考博文:

http://blog.csdn.net/zero__007/article/details/50571703#

http://www.cnblogs.com/leetieniu2014/p/5403277.htm  

相關文章
相關標籤/搜索