Java8 新特性連載——內置函數式接口之Predicates

Java8引入函數式接口(關於函數式接口,可以戳 ),同時在JDK中也內置了大量非常好用的函數式接口,它們的存在能讓你的編碼生涯更加輕鬆。實際上用過Google Guava庫的童鞋應該就相當有體會,本文就花一分鐘闡述Predicates的用法

一、應用場景描述

在實際項目中,經常會遇到從一個集合中依據某種過濾條件篩選出合適的對象,然後放入一個新的集合中,例如有個貓類:

public class Cat {
private String name;
private Integer type;
private Integer age;
// set get 忽略
}

然後我們有一個貓的集合:

List cats = new ArrayList<>();

現在我們需要根據類別篩選出加菲貓,我們都這麼幹:

public List getGarfield() {
List garfields = new ArrayList<>();
for(Cat cat:cats) {
if(cat.getType().equals("Garfield")) {
garfields.add(cat);
}
}
return garfields;
}

過了段時間,我們又需要找出年齡大於某個年齡的貓,我們又寫了個方法:

public List getCatsByAgeGreatThan(int age) {
List bigcats = new ArrayList<>();
for(Cat cat:cats) {
if(cat.getAge() > 2) {
bigcats.add(cat);
}
}
}

以後可能還會有更多的查詢要求出來,但所有這些代碼差異及其小,僅僅只是if的條件不一樣,然後你寫了一堆的查詢方法,坑不?

這下好了,Java8的Predicates來拯救你了,用過Google Guava庫的童鞋肯定對這個詞語不會陌生,這回Java把它內置到JDK了。我們來看看它是如何拯救你的。

二、瞭解一下Predicates

我們查看java源碼不難發現,實際上Predicate就是一個函數接口,它只有一個抽象方法:

boolean test(T t);

還有三個默認實現的方法,分別實現了最常用的邏輯判斷:and、or和not

接口就是如此簡單,那麼怎麼用呢?

三、用法詳解

之前,我們為了滿足需求,寫了一堆的查詢方法,如果用Predicate,我們只需要一個方法就可以了:

public List query(Predicate predicate) {
List result = new ArrayList<>();
for(Cat cat:cats) {
if(predicate.test(cat)) {
result.add(cat);
}
}
return result;
}

然後我們可以這麼查詢加菲貓:

List garfields = query(c -> "Garfield".equals(c.getType()));

然後這麼查找大於兩歲的貓:

List garfields = query(c -> c.getAge() > 2);

我們還可以組合條件,例如查找大於兩歲的加菲貓:

Predicate p = (c) -> "Garfield".equals(c.getType());
List garfields = query(p.and(c -> c.getAge() > 2));

真是用過一次就愛上了有木有。

四、進一步瞭解

上面的闡述是我們為了闡述Predicate用法而展開的解釋,實際上對於容器的過濾,Java8已經在內部就已經實現了,我們直接就可以用容器的stream來達到過濾的目的,連query方法都不用寫,一句話就搞定了:

List result = cats.stream().filter(c -> c.getAge() > 2).collect(Collectors.toList());

注意其中的filter,filter的參數就是Predicate,哇哦,實在是太方便啦……


分享到:


相關文章: