Java?Stream流中的filter()使用方法舉例詳解
前言
filter()
是 Java Stream API 中的一個(gè)中間操作,用于根據(jù)給定的條件篩選流中的元素。它接收一個(gè) Predicate
(斷言,即返回 boolean
的函數(shù))作為參數(shù),篩選出滿足條件的元素,并將它們收集到一個(gè)新的流中。
1. 基本用法
filter()
允許你基于某些條件篩選流中的元素。例如,如果你有一個(gè)整數(shù)流,并且只想保留其中的偶數(shù),可以使用 filter()
來實(shí)現(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]
在這個(gè)例子中:
filter(n -> n % 2 == 0)
:是一個(gè)篩選條件,用于保留那些能被 2 整除的數(shù)字,即偶數(shù)。filter()
會(huì)遍歷流中的每個(gè)元素,使用該條件進(jìn)行檢查,滿足條件的元素會(huì)繼續(xù)留在流中,不滿足條件的元素會(huì)被丟棄。
2. Predicate 函數(shù)
filter()
的參數(shù)是一個(gè) Predicate
接口,這個(gè)接口只有一個(gè)抽象方法 boolean test(T t)
,它接收一個(gè)輸入并返回一個(gè) boolean
值。這個(gè) 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]
在這個(gè)例子中,n -> n > 3
是一個(gè) Predicate
,它表示篩選出大于 3 的數(shù)字。filter()
方法根據(jù)這個(gè) Predicate
來保留滿足條件的元素。
3. 鏈?zhǔn)秸{(diào)用 filter()
你可以多次調(diào)用 filter()
,來對流中的元素應(yīng)用多個(gè)條件。比如:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); List<Integer> filteredNumbers = numbers.stream() .filter(n -> n > 3) // 第一個(gè)條件: 大于 3 .filter(n -> n < 8) // 第二個(gè)條件: 小于 8 .collect(Collectors.toList()); System.out.println(filteredNumbers); // 輸出: [4, 5, 6, 7]
這里,filter()
被調(diào)用了兩次:
- 第一個(gè)
filter(n -> n > 3)
:篩選出大于 3 的數(shù)字。 - 第二個(gè)
filter(n -> n < 8)
:在剩余的數(shù)字中篩選出小于 8 的數(shù)字。
最終結(jié)果就是同時(shí)滿足這兩個(gè)條件的元素 [4, 5, 6, 7]
。
4. 空流
filter()
操作之后,流可能會(huì)變成空流。如果沒有任何元素滿足 filter()
的條件,流會(huì)變成空流,但不會(huì)拋出異常。這種情況下,后續(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); // 輸出: []
在這個(gè)例子中,filter(n -> n > 10)
篩選出大于 10 的元素,但流中沒有元素滿足這個(gè)條件,所以最終返回的是一個(gè)空列表 []
。
5. filter() 的惰性求值
filter()
是一種惰性操作,也就是 中間操作。它本身并不會(huì)立即執(zhí)行,而是等到流上的終端操作(如 collect()
、forEach()
)被調(diào)用時(shí)才會(huì)執(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)用時(shí),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]
在這個(gè)例子中:
filter(word -> word.length() > 5)
:篩選出長度大于 5 的單詞。map(String::toUpperCase)
:將剩下的單詞轉(zhuǎn)換為大寫。collect(Collectors.toList())
:將流結(jié)果收集為一個(gè)List
。
7. 組合多個(gè) Predicate 條件
有時(shí)候你可能需要對流中的元素應(yīng)用多個(gè)條件。你可以通過 Predicate
的 and()
、or()
、negate()
等方法組合多個(gè)條件。
示例:篩選出大于 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]
這種方式能夠增強(qiáng)代碼的可讀性和重用性。
8. 在對象集合中使用 filter()
filter()
不僅可以用于簡單類型的流(如 Integer
、String
),也可以用于復(fù)雜對象的流。例如,在一個(gè)包含 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()
是一個(gè)中間操作,用于根據(jù)給定的Predicate
對流中的元素進(jìn)行篩選,保留符合條件的元素。- 它不會(huì)改變元素的類型,只會(huì)決定哪些元素可以繼續(xù)傳遞到下一個(gè)流操作。
- 由于
filter()
是惰性求值的,中間操作只有在終端操作被調(diào)用時(shí)才會(huì)執(zhí)行。 filter()
適合用于各種復(fù)雜對象的篩選,并且可以與map()
等其他流操作結(jié)合使用。
到此這篇關(guān)于Java Stream流中的filter()使用方法的文章就介紹到這了,更多相關(guān)Java Stream流中filter()使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java 8 Stream filter流式過濾器詳解
- java中處理stream.filter()的實(shí)例代碼
- Java中Stream?Filter多條件篩選過濾代碼舉例
- java基礎(chǔ)理論Stream的Filter與謂詞邏輯
- Java中的FilterOutputStream 簡介_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
- Java中的 FilterInputStream簡介_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
- Java中FilterInputStream和FilterOutputStream的用法詳解
- java streamfilter list 過濾的實(shí)現(xiàn)
相關(guān)文章
maven工程打包引入本地jar包的實(shí)現(xiàn)
我們需要將jar包發(fā)布到一些指定的第三方Maven倉庫,本文主要介紹了maven工程打包引入本地jar包的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-02-02SpringBoot結(jié)合Neo4j自定義cypherSql的方法
這篇文章主要介紹了SpringBoot結(jié)合Neo4j自定義cypherSql,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-11-11Java8中對泛型目標(biāo)類型推斷方法的改進(jìn)
這篇文章主要介紹了Java8中對泛型目標(biāo)類型推斷方法的改進(jìn),需要的朋友可以參考下2014-06-06Java基礎(chǔ)之多線程方法狀態(tài)和創(chuàng)建方法
Java中可以通過Thread類和Runnable接口來創(chuàng)建多個(gè)線程,下面這篇文章主要給大家介紹了關(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í)價(jià)值,需要的朋友可以參考下2020-11-11基于springboot服務(wù)間Feign調(diào)用超時(shí)的解決方案
這篇文章主要介紹了基于springboot服務(wù)間Feign調(diào)用超時(shí)的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07SpringBoot整合Ureport2報(bào)表及常見使用方法
這篇文章主要介紹了SpringBoot整合Ureport2報(bào)表及常見使用方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01java實(shí)現(xiàn)的xml格式化實(shí)現(xiàn)代碼
這篇文章主要介紹了java實(shí)現(xiàn)的xml格式化實(shí)現(xiàn)代碼,需要的朋友可以參考下2016-11-11