Java 8 起為 Collection 集合新增了一個 removeIf(Predicate filter) 方法,該方法將會批量刪除符合 filter 條件的所有元素。該方法需要一個 Predicate 對象作為參數,Predicate 也是函數式接口,因此可使用 Lambda 表達式作為參數。
如下程序示范了使用 Predicate 來過濾集合。
public class ForeachTest {
public static void main(String[] args) {
// 創建一個集合
Collection objs = new HashSet();
objs.add(new String("C語言中文網Java教程"));
objs.add(new String("C語言中文網C++教程"));
objs.add(new String("C語言中文網C語言教程"));
objs.add(new String("C語言中文網Python教程"));
objs.add(new String("C語言中文網Go教程"));
// 使用Lambda表達式(目標類型是Predicate)過濾集合
objs.removeIf(ele -> ((String) ele).length() < 12);
System.out.println(objs);
}
}
上面程序中第 11 行代碼調用了 Collection 集合的 removeIf() 方法批量刪除集合中符合條件的元素,程序傳入一個 Lambda 表達式作為過濾條件。所有長度小于 12 的字符串元素都會被刪除。編譯、運行這段代碼,可以看到如下輸出:
[C語言中文網Java教程, C語言中文網Python教程]
使用 Predicate 可以充分簡化集合的運算,假設依然有上面程序所示的 objs 集合,如果程序有如下三個統計需求:
統計集合中出現“C語言中文網”字符串的數量。
統計集合中出現“Java”字符串的數量。
統計集合中出現字符串長度大于 12 的數量。
此處只是一個假設,實際上還可能有更多的統計需求。如果采用傳統的編程方式來完成這些需求,則需要執行三次循環,但采用 Predicate 只需要一個方法即可。下面代碼示范了這種用法。
public class ForeachTest2 {
public static void main(String[] args) {
// 創建一個集合
Collection objs = new HashSet();
objs.add(new String("C語言中文網Java教程"));
objs.add(new String("C語言中文網C++教程"));
objs.add(new String("C語言中文網C語言教程"));
objs.add(new String("C語言中文網Python教程"));
objs.add(new String("C語言中文網Go教程"));
// 統計集合中出現“C語言中文網”字符串的數量
System.out.println(calAll(objs, ele -> ((String) ele).contains("C語言中文網")));
// 統計集合中出現“Java”字符串的數量
System.out.println(calAll(objs, ele -> ((String) ele).contains("Java")));
// 統計集合中出現字符串長度大于 12 的數量
System.out.println(calAll(objs, ele -> ((String) ele).length() > 12));
}
public static int calAll(Collection books, Predicate p) {
int total = 0;
for (Object obj : books) {
// 使用Predicate的test()方法判斷該對象是否滿足Predicate指定的條件
if (p.test(obj)) {
total++;
}
}
return total;
}
}
輸出結果為:
5 1 1
上面程序先定義了一個 calAll() 方法,它使用 Predicate 判斷每個集合元素是否符合特定條件,條件將通過 Predicate 參數動態傳入。從上面程序中第 11、13、15 行代碼可以看到,程序傳入了 3 個 Lambda 表達式,其目標類型都是 Predicate,這樣 calAll() 方法就只會統計滿足 Predicate 條件的圖書。