Java 9中的新流收集器
1.概述
Java 8中添加了Collectors
,它有助於將輸入元素累積到可變容器中,例如Map
, List
和Set
。
在本文中,我們將探索Java 9中添加的兩個新收集器: Collectors.filtering
和**Collectors.flatMapping**
與Collectors.groupingBy
結合使用,提供了元素的智能集合。
2. Filtering Collector
Collectors.filtering
與Stream filter()
類似;它用於filtering
輸入元素,但用於不同的場景。在流鏈中使用Stream's
filter
,而filtering
是設計為與groupingBy
一起使用的Collector
。
使用Stream's
filter
,首先過濾值,然後將其分組。這樣,過濾掉的值就消失了,也沒有踪跡。如果需要跟踪,則需要首先進行分組,然後應用Collectors.filtering
實際執行的過濾。
Collectors.filtering
具有一個用於過濾輸入元素的函數,以及一個收集器來收集過濾後的元素:
@Test
public void givenList_whenSatifyPredicate_thenMapValueWithOccurences() {
List<Integer> numbers = List.of(1, 2, 3, 5, 5);
Map<Integer, Long> result = numbers.stream()
.filter(val -> val > 3)
.collect(Collectors.groupingBy(i -> i, Collectors.counting()));
assertEquals(1, result.size());
result = numbers.stream()
.collect(Collectors.groupingBy(i -> i,
Collectors.filtering(val -> val > 3, Collectors.counting())));
assertEquals(4, result.size());
}
3. FlatMapping Collector
該Collectors.flatMapping
類似於Collectors.mapping
但具有更細粒度的目標。這兩個收集器都具有一個函數和一個收集元素的收集器,但是flatMapping
函數接受元素Stream
,然後由收集器對其進行積累。
讓我們看下面的模型類:
class Blog {
private String authorName;
private List<String> comments;
// constructor and getters
}
Collectors.flatMapping
使我們可以跳過中間集合,並直接寫入單個容器,該容器映射到Collectors.groupingBy
定義的組:
@Test
public void givenListOfBlogs_whenAuthorName_thenMapAuthorWithComments() {
Blog blog1 = new Blog("1", "Nice", "Very Nice");
Blog blog2 = new Blog("2", "Disappointing", "Ok", "Could be better");
List<Blog> blogs = List.of(blog1, blog2);
Map<String, List<List<String>>> authorComments1 = blogs.stream()
.collect(Collectors.groupingBy(Blog::getAuthorName,
Collectors.mapping(Blog::getComments, Collectors.toList())));
assertEquals(2, authorComments1.size());
assertEquals(2, authorComments1.get("1").get(0).size());
assertEquals(3, authorComments1.get("2").get(0).size());
Map<String, List<String>> authorComments2 = blogs.stream()
.collect(Collectors.groupingBy(Blog::getAuthorName,
Collectors.flatMapping(blog -> blog.getComments().stream(),
Collectors.toList())));
assertEquals(2, authorComments2.size());
assertEquals(2, authorComments2.get("1").size());
assertEquals(3, authorComments2.get("2").size());
}
Collectors.mapping
將所有分組的作者的評論映射到收藏者的容器(即List
而此中間收藏集通過flatMapping
刪除,因為它提供了直接將評論列表映射到收藏家的容器的流。
4。結論
本文說明了Java9
引入的新Collectors
的Java9
即**Collectors.filtering()
和Collectors.flatMapping()
與Collectors.groupingBy()
結合使用**。
這些收集器也可以與Collectors.partitioningBy()
一起使用,但是它僅根據條件創建兩個分區,並且沒有利用收集器的實際功能;因此不在本教程範圍之內。
本教程中的代碼片段的完整源代碼可在GitHub上獲得。