Java?Stream流中的filter()使用方法舉例詳解
前言
filter() 是 Java Stream API 中的一個中間操作,用于根據(jù)給定的條件篩選流中的元素。它接收一個 Predicate(斷言,即返回 boolean 的函數(shù))作為參數(shù),篩選出滿足條件的元素,并將它們收集到一個新的流中。
1. 基本用法
filter() 允許你基于某些條件篩選流中的元素。例如,如果你有一個整數(shù)流,并且只想保留其中的偶數(shù),可以使用 filter() 來實現(xiàn):
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
List<Integer> evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0) // 保留偶數(shù)
.collect(Collectors.toList()); // 終端操作,將結(jié)果收集為 List
System.out.println(evenNumbers); // 輸出: [2, 4, 6]
在這個例子中:
filter(n -> n % 2 == 0):是一個篩選條件,用于保留那些能被 2 整除的數(shù)字,即偶數(shù)。filter()會遍歷流中的每個元素,使用該條件進行檢查,滿足條件的元素會繼續(xù)留在流中,不滿足條件的元素會被丟棄。
2. Predicate 函數(shù)
filter() 的參數(shù)是一個 Predicate 接口,這個接口只有一個抽象方法 boolean test(T t),它接收一個輸入并返回一個 boolean 值。這個 Predicate 用來定義篩選條件。
示例:篩選大于 3 的數(shù)字
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> greaterThanThree = numbers.stream()
.filter(n -> n > 3) // 保留大于 3 的數(shù)字
.collect(Collectors.toList());
System.out.println(greaterThanThree); // 輸出: [4, 5]
在這個例子中,n -> n > 3 是一個 Predicate,它表示篩選出大于 3 的數(shù)字。filter() 方法根據(jù)這個 Predicate 來保留滿足條件的元素。
3. 鏈?zhǔn)秸{(diào)用 filter()
你可以多次調(diào)用 filter(),來對流中的元素應(yīng)用多個條件。比如:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> filteredNumbers = numbers.stream()
.filter(n -> n > 3) // 第一個條件: 大于 3
.filter(n -> n < 8) // 第二個條件: 小于 8
.collect(Collectors.toList());
System.out.println(filteredNumbers); // 輸出: [4, 5, 6, 7]
這里,filter() 被調(diào)用了兩次:
- 第一個
filter(n -> n > 3):篩選出大于 3 的數(shù)字。 - 第二個
filter(n -> n < 8):在剩余的數(shù)字中篩選出小于 8 的數(shù)字。
最終結(jié)果就是同時滿足這兩個條件的元素 [4, 5, 6, 7]。
4. 空流
filter() 操作之后,流可能會變成空流。如果沒有任何元素滿足 filter() 的條件,流會變成空流,但不會拋出異常。這種情況下,后續(xù)的中間操作仍然可以應(yīng)用在空流上,只是沒有元素可以處理:
List<Integer> numbers = Arrays.asList(1, 2, 3);
List<Integer> result = numbers.stream()
.filter(n -> n > 10) // 沒有元素滿足條件
.collect(Collectors.toList());
System.out.println(result); // 輸出: []
在這個例子中,filter(n -> n > 10) 篩選出大于 10 的元素,但流中沒有元素滿足這個條件,所以最終返回的是一個空列表 []。
5. filter() 的惰性求值
filter() 是一種惰性操作,也就是 中間操作。它本身并不會立即執(zhí)行,而是等到流上的終端操作(如 collect()、forEach())被調(diào)用時才會執(zhí)行。
例如:
Stream<Integer> stream = Stream.of(1, 2, 3, 4)
.filter(n -> {
System.out.println("Filtering: " + n);
return n % 2 == 0;
});
System.out.println("Before terminal operation");
// 終端操作,觸發(fā) filter 執(zhí)行
List<Integer> evenNumbers = stream.collect(Collectors.toList());
System.out.println("After terminal operation: " + evenNumbers);
輸出結(jié)果為:
Before terminal operation
Filtering: 1
Filtering: 2
Filtering: 3
Filtering: 4
After terminal operation: [2, 4]
可以看到,在調(diào)用終端操作 collect() 之前,filter() 并沒有執(zhí)行;只有當(dāng)終端操作被調(diào)用時,filter() 才真正開始過濾元素。
6. 結(jié)合其他流操作使用
filter() 常常與其他流操作結(jié)合使用,比如 map()、sorted() 等。
示例:filter() 和 map() 結(jié)合使用
List<String> words = Arrays.asList("apple", "banana", "cherry", "date");
List<String> result = words.stream()
.filter(word -> word.length() > 5) // 篩選長度大于 5 的單詞
.map(String::toUpperCase) // 將符合條件的單詞轉(zhuǎn)換為大寫
.collect(Collectors.toList());
System.out.println(result); // 輸出: [BANANA, CHERRY]
在這個例子中:
filter(word -> word.length() > 5):篩選出長度大于 5 的單詞。map(String::toUpperCase):將剩下的單詞轉(zhuǎn)換為大寫。collect(Collectors.toList()):將流結(jié)果收集為一個List。
7. 組合多個 Predicate 條件
有時候你可能需要對流中的元素應(yīng)用多個條件。你可以通過 Predicate 的 and()、or()、negate() 等方法組合多個條件。
示例:篩選出大于 2 且是偶數(shù)的數(shù)字
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
List<Integer> result = numbers.stream()
.filter(n -> n > 2 && n % 2 == 0) // 組合條件: 大于 2 且為偶數(shù)
.collect(Collectors.toList());
System.out.println(result); // 輸出: [4, 6]
你也可以使用 Predicate 的組合方法:
Predicate<Integer> greaterThanTwo = n -> n > 2;
Predicate<Integer> isEven = n -> n % 2 == 0;
List<Integer> result = numbers.stream()
.filter(greaterThanTwo.and(isEven)) // 使用 Predicate 的 and() 方法
.collect(Collectors.toList());
System.out.println(result); // 輸出: [4, 6]
這種方式能夠增強代碼的可讀性和重用性。
8. 在對象集合中使用 filter()
filter() 不僅可以用于簡單類型的流(如 Integer、String),也可以用于復(fù)雜對象的流。例如,在一個包含 Person 對象的列表中篩選年齡大于 18 的人:
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return name + " (" + age + ")";
}
}
List<Person> people = Arrays.asList(
new Person("Alice", 22),
new Person("Bob", 17),
new Person("Charlie", 20)
);
List<Person> adults = people.stream()
.filter(person -> person.age > 18) // 篩選年齡大于 18 的人
.collect(Collectors.toList());
System.out.println(adults); // 輸出: [Alice (22), Charlie (20)]
總結(jié):
filter()是一個中間操作,用于根據(jù)給定的Predicate對流中的元素進行篩選,保留符合條件的元素。- 它不會改變元素的類型,只會決定哪些元素可以繼續(xù)傳遞到下一個流操作。
- 由于
filter()是惰性求值的,中間操作只有在終端操作被調(diào)用時才會執(zhí)行。 filter()適合用于各種復(fù)雜對象的篩選,并且可以與map()等其他流操作結(jié)合使用。
到此這篇關(guān)于Java Stream流中的filter()使用方法的文章就介紹到這了,更多相關(guān)Java Stream流中filter()使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot結(jié)合Neo4j自定義cypherSql的方法
這篇文章主要介紹了SpringBoot結(jié)合Neo4j自定義cypherSql,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-11-11
Java基礎(chǔ)之多線程方法狀態(tài)和創(chuàng)建方法
Java中可以通過Thread類和Runnable接口來創(chuàng)建多個線程,下面這篇文章主要給大家介紹了關(guān)于Java基礎(chǔ)之多線程方法狀態(tài)和創(chuàng)建方法的相關(guān)資料,需要的朋友可以參考下2021-09-09
基于java查找并打印輸出字符串中字符出現(xiàn)次數(shù)
這篇文章主要介紹了基于java查找并打印輸出字符串中字符出現(xiàn)次數(shù),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-11-11
基于springboot服務(wù)間Feign調(diào)用超時的解決方案
這篇文章主要介紹了基于springboot服務(wù)間Feign調(diào)用超時的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07

