上一篇文章中,咱們整體介紹了建立函數式接口實例的幾種方式以及Java8中接口新增的默認方法特性,接下來咱們來看下Java8中已經爲咱們提供的幾種典型的函數式接口
先看一個示例編程
public class FunctionTest { public static void main(String[] args) { FunctionTest functionTest = new FunctionTest(); int i2 = functionTest.add2(2); int i3 = functionTest.add3(2); int i4 = functionTest.add4(2); } //邏輯提早定義好 public int add2(int i){ return i + 2; } //邏輯提早定義好 public int add3(int i){ return i + 3; } //邏輯提早定義好 public int add4(int i){ return i + 4; } }
FunctionTest中定義了三個方法,分別把參數加2,加3,加4而後分別把結果返回,那若是之後還要取到參數的平方或者各類其餘的運算,就還須要定義更多的處理方法。接下來看下若是使用Java8提供的Function接口會有哪些改進
首先看下Function接口定義segmentfault
@FunctionalInterface public interface Function<T, R> { /** * Applies this function to the given argument. * * @param t the function argument * @return the function result */ R apply(T t); . .省略 . }
該函數式接口惟一的抽象方法apply接收一個參數,有返回值。看下使用方式api
public class FunctionTest { public static void main(String[] args) { FunctionTest functionTest = new FunctionTest(); int result2 = functionTest.compute(5, num -> num + 2); int result3 = functionTest.compute(5, num -> num + 2); int result4 = functionTest.compute(5, num -> num + 2); int results = functionTest.compute(5, num -> num * num); } //調用時傳入邏輯 public int compute(int i, Function<Integer,Integer> function){ Integer result = function.apply(i); return result; } }
咱們在FunctionTest中定義了compute方法,方法的第一個參數是要運算的數據,第二個參數是函數式接口Function的實例,當執行compute方法時,會將第一個參數交給第二個參數Function中的apply方法處理,而後返回結果。
這樣咱們能夠將方法定義的更抽象,代碼重用性也就越高,每次將要計算的數據和計算邏輯一塊兒做爲參數傳遞給compute方法就能夠。是否是有點體驗到函數式編程的靈活之處。
注:由於表達式只有一行語句 num -> num + 2 能夠省略了return 關鍵字 若是爲了更加直觀能夠寫成 num -> return num + 2app
Supplier接口,默認抽象方法get不接收參數,有返回值函數式編程
@FunctionalInterface public interface Supplier<T> { /** * Gets a result. * * @return a result */ T get(); }
相似工廠模式函數
public class SupplierTest { public static void main(String[] args) { Supplier<String> supplier = String::new; String s = supplier.get(); } }
這裏使用構造方法引用的方式建立Supplier實例,經過get直接返回String對象this
Predicate接口lua
@FunctionalInterface public interface Predicate<T> { /** * Evaluates this predicate on the given argument. * * @param t the input argument * @return {@code true} if the input argument matches the predicate, * otherwise {@code false} */ boolean test(T t); . .省略 . }
接收一個參數,返回布爾類型,使用方式code
public class PredicateTest { public static void main(String[] args) { Predicate<String> predicate = s -> s.length() > 5; System.out.println(predicate.test("hello")); } }
定義了一個接收一個參數返回布爾值的lambda表達式,賦值給predicate,就能夠直接對傳入參數進行校驗對象
再看一個Predicate例子
public class PredicateTest { public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); PredicateTest predicateTest = new PredicateTest(); List<Integer> result = predicateTest.conditionFilter(list, integer -> integer > 5); result.forEach(System.out::println); } public List<Integer> conditionFilter(List<Integer> list, Predicate<Integer> predicate){ return list.stream().filter(predicate).collect(Collectors.toList()); } }
這段程序的邏輯是找到集合裏大於5的數據,打印到控制檯。咱們具體分析一下conditionFilter方法,第一個參數是待遍歷的集合,第二個參數是Predicate類型的實例,還記得Predicate接口中的抽象方法定義嗎,接收一個參數返回布爾類型。list.stream()是建立了一個針對此集合的Stream對象(先簡單認識一下),而後調用Stream的filter方法對結果進行過濾,過濾的條件就是Predicate接口的實現,最後collect(Collectors.toList());是將過濾後的結果收集起來放置到一個新的集合中並返回。
其中涉及到Srteam api的知識點咱們會在後續章節中詳細介紹,如今只關心Predicate的使用就能夠。
接下來調用conditionFilter方法
List<Integer> result = predicateTest.conditionFilter(list, integer -> integer > 5);
list是待遍歷的集合
integer -> integer > 5 lambda表達式是對Predicate接口的具體實現
result.forEach(System.out::println);
最後,方法引用實例化一個Consumer對象,把結果輸出到控制檯。
能夠看出,lambda表達式和stream api結合起來使用讓代碼更簡潔更加語義化,即便以前沒接觸過stream api也能大概看出conditionFilter方法的功能。
小結:本篇繼續介紹Java8函數式編程模型,介紹了幾個內置的函數式接口使用方式,並在最後一個示例引出stream api知識點,後續會對stream api進行詳細的介紹,若是以爲本篇文章對你有所幫助幫忙贊一下。