New Stream Collectors in Java 9
¶1. Overview
Collectors were added in Java 8 which helped accumulate input elements into mutable containers such as Map, List, and Set.
In this article, we’re going to explore two new collectors added in Java 9: Collectors.filtering and Collectors.flatMapping used in combination with Collectors.groupingBy providing intelligent collections of elements.
¶2. Filtering Collector
The Collectors.filtering is similar to the Stream filter(); it’s used for filtering input elements but used for different scenarios. The Stream’s filter is used in the stream chain whereas the filtering is a Collector which was designed to be used along with grouping By.
Collectors.filtering 与 Stream filter() 有点像,它用于过滤输入元素,但用于不同的场景下。Stream’s filter 被用于stream链,而 Collectors.filtering 被设计为与 grouping By结合使用。
With Stream’s filter, the values are filtered first and then it’s grouped. In this way, the values which are filtered out are gone and there is no trace of it. If we need a trace then we would need to group first and then apply filtering which actually the Collectors.filtering does.
使用 Stream’s filter时,输入元素首先会被过滤掉,然后才会被分组。如果我们需要在分组之后才对其进行过滤的话,应该使用 Collectors.filtering 。
The Collectors.filtering takes a function for filtering the input elements and a collector to collect the filtered elements:
Collectors.filtering 使用函数来过滤和收集过滤后的元素:
public void givenList_whenSatifyPredicate_thenMapValueWithOccurences() {
List<Integer> numbers = List.of(1, 2, 3, 5, 5);
Map<Integer, Long> result = numbers.stream()
// 此时stream中只有[5, 5]
.filter(val -> val > 3)
// 然后分组统计,这将会失去对过滤掉元素的统计结果,即使为0
.collect(Collectors.groupingBy(i -> i, Collectors.counting()));
// result => { 5:2 }
assertEquals(1, result.size());
result = numbers.stream()
// 先进行分组[ [1], [2], [3], [5, 5] ]
.collect(Collectors.groupingBy(i -> i,
// 然后过滤掉出每组中大于3的值进行统计
Collectors.filtering(val -> val > 3, Collectors.counting())));
// result => { 1:0, 2:0, 3:0, 5:2 }
assertEquals(4, result.size());
}