Java 9中的新流收集器

1.概述

Java 8中添加了Collectors ,它有助於將輸入元素累積到可變容器中,例如MapListSet

在本文中,我們將探索Java 9中添加的兩個新收集器: Collectors.filtering**Collectors.flatMapping**Collectors.groupingBy結合使用,提供了元素的智能集合。

2. Filtering Collector

Collectors.filteringStream 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引入的新CollectorsJava9即**Collectors.filtering()Collectors.flatMapping()Collectors.groupingBy()結合使用**。

這些收集器也可以與Collectors.partitioningBy()一起使用,但是它僅根據條件創建兩個分區,並且沒有利用收集器的實際功能;因此不在本教程範圍之內。

本教程中的代碼片段的完整源代碼可在GitHub上獲得