java8學習筆記(一):FunctionalInterface與Stream

引言

最近在工做中用到java8的Stream流式操做不少,於是對相關概念與實操做簡單概括與總結:java

函數式接口

函數式接口是java8新加入特性,爲配合lambda表達式而生。lambda表達式與匿名錶達式異同可參考  時光隧道 。判斷一個接口是否爲函數式接口特別簡單,只需知足一個條件便可:一個接口有且僅有一個函數(接口默認static及default方法除外)! 即便該接口未被@FunctionalInterface註解標記,但仍爲一個函數式接口

咱們來看一個示例:數據庫

Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("hello the thread.");
    }
});
thread.start();

使用lambda表達式建立方式爲:
ide

Thread thread=new Thread(()-> System.out.println("hello"));
thread.start();

從示例能夠看出,使用lambda表達式配合函數式接口能夠大大精簡代碼,那麼函數式接口有什麼用呢?
函數

使用lambda表達式調用該函數,將接口方法的實現封裝到具體方法,實際也是實現且建立一個接口對象,將方法做爲接口實現。更加抽象,只能看到接口方法內部實現。

那麼,咱們可將常見的使用方式概括爲:
post

方法引用經過::將方法隸屬和方法自身鏈接起來,如:ClassName :: methodName
1. 靜態方法   (args) -> ClassName.staticMethod(args)   轉換成   ClassName::staticMethod
2. 實例方法   (args) -> args.instanceMethod()   轉換成   ClassName::instanceMethod
3. 外部的實例方法   (args) -> ext.instanceMethod(args)   轉換成   ext::instanceMethod(args)

咱們來看一個完整的示例:
this

@FieldDefaults(level = AccessLevel.PRIVATE)
@ToString
public class Kid {

    Integer age;
    
    String name;

    public Kid(int age, String name) {
        this.age = age;
        this.name = name;
    }
    public Integer getAge() {return age;}
    public void setAge(Integer age) {this.age = age;}
    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
}
public class MethodReference {

    public static void main(String[] args) {
        List<Kid> kids = Arrays.asList(
                new Kid(10, "奶酪1"),
                new Kid(8, "奶酪3"),
                new Kid(11, "奶酪2")
        );

        // 採用lambda表達式排序
        kids.sort((Kid a, Kid b) -> compare(a.getAge(), b.getAge()));
        kids.forEach(System.out::println);
        // 採用方法引用排序
        kids.sort(Comparator.comparing(Kid::getName));
        kids.forEach(System.out::println);
    }

}

輸出以下:
spa

Kid(age=8, name=奶酪3),Kid(age=10, name=奶酪1),Kid(age=11, name=奶酪2)

Kid(age=10, name=奶酪1),Kid(age=11, name=奶酪2),Kid(age=8, name=奶酪3)



java8新增的java.util.function包,爲咱們提供了諸多的函數式接口,概括以下:


code

函數式接口名 參數類型 接口說明
Supplier Supplier< T > 提供T對象(例如工廠),不接收值
Consumer Consumer< T > 接收T對象,不返回值
Predicate Predicate< T > 接收T對象並返回boolean
Function Function< T, R > 接收T對象,返回R對象
UnaryOperator UnaryOperator< T > 接收T對象,返回T對象
BiConsumer BiConsumer<T, U> 接收T對象和U對象,不返回值
BiPredicate BiPredicate<T, U> 接收T對象和U對象,返回boolean
BiFunction BiFunction<T, U, R> 接收T對象和U對象,返回R對象
BinaryOperator BinaryOperator< T > 接收兩個T對象,返回T對象
函數式接口須配合Stream才能發揮其最大的用處,接下來咱們對Steam接口方法常見使用方式進行舉例。

Stream淺析

何爲Stream ?對象

流(Stream)是Java API的新成員,它容許以聲明性的方式處理數據集合(相似於數據庫查詢語句).暫且理解爲遍歷數據集的高級迭代器。

咱們能夠用一圖來概括Stream的通用場景:
steam通用示意圖blog

相關文章
相關標籤/搜索