JDK提供了大量的函數式接口,方便咱們開發的時候無需本身編寫接口,這些接口都比較通用,學會他們而且在工做中使用,不只方便的解決問題,並且十分優雅。
Supplier接口的源碼比較簡單,只有一個方法。函數
@FunctionalInterface public interface Supplier<T> { /** * Gets a result. * * @return a result */ T get(); }
get方法沒有參數,可是有一個返回值,該返回值是泛型參數指定的類型。該方法用於建立指定類型的對象。測試
在嘗試使用Supplier接口以前,咱們先看這樣的一個場景:嘗試從某個地方獲取一個對象,若是沒有獲取到,那麼咱們就本身造一個默認的對象。this
咱們先定義一個對象Person.code
public class Person { private final String name; private final Integer age; public Person(String name, Integer age){ this.name = name; this.age = age; } }
如今來測試:getPerson 方法經過 name 來從列表中查找Person對象,若是查到就返回,沒有查到返回 null. 在main方法中咱們調用該方法,而且判斷返回結果爲空的時候就建立一個默認的Person 對象,而後繼續後面的邏輯。對象
public class SupplierTest { private static List<Person> personList = new ArrayList<Person>() { { add(new Person("lisi", 20)); add(new Person("zhangsan", 23)); } }; public static void main(String[] args) { String name = "wangwu"; Person person = getPerson(name); if (person == null) { person = new Person(name, 10); } //後續處理 System.out.println(person); } public static Person getPerson(String name) { for (Person person : personList) { if (person.getName().equals(name)) { return person; } } return null; } }
上面的這種寫法雖然能解決問題,但如今可使用Supplier簡化代碼。接口
public class SupplierTest { private static List<Person> personList = new ArrayList<Person>() { { add(new Person("lisi", 20)); add(new Person("zhangsan", 23)); } }; public static void main(String[] args) { String name = "wangwu"; Person person = getPerson(name, () -> new Person(name, 10)); //後續處理 System.out.println(person); } public static Person getPerson(String name, Supplier<Person> supplier) { return personList.stream() .filter(e -> e.getName().equals(name)) .findAny() .orElse(supplier.get()); } }
這裏咱們在 getPerson
方法中添加了一個參數 Supplier<Person> supplier
,在沒有獲取到須要尋找的對象的時候,由調用方提供的Supplier來生成一個默認的對象。那麼咱們在main方法中調用 getPerson
的時候就無需進行空判斷,代碼也就比較清楚簡單。開發
Person person = getPerson(name, () -> new Person(name, 10));
這種模式看起來很是直觀,對於這種場景應該鼓勵使用。getPerson的第一個參數是name,若是使用該name值查找到Person對象,那麼就使用它,若是查找爲空,那麼咱們本身建立一個默認的Person實例,也就是上面的Lambda表達式的內容。get