New features of Java 9 Stream Collectors
Java 8 introduces Collectors, which are used to accumulate input elements into mutable containers such as Map, List and Set. This article takes a look at the two new Collectors in Java 9: Collectors.filtering and Collectors.flatMapping, which are mainly used to provide intelligent element collections together with Collectors.groupingBy.
Collectors.filtering method
Collectors.filtering method is similar to the Stream filter() method, which is used to filter input elements, but the usage scenarios of the two are different. Stream filter() is used in the stream chaining method, while the Collectors.filtering method is designed to be used with groupingBy.
Stream filter() first filters elements and then groups them. Filtered values are discarded and cannot be traced retroactively. If you need to track things you need to group first and then filter, that's exactly what Collectors.filtering can do.
Collectors.filtering takes function parameters to filter the input parameters, and then collects the filtered elements:
@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()); }
Collectors.flatMapping method
Collectors .flatMapping is similar to the Collectors.mapping method, but more granular. Both take a function and a collector parameter to collect elements, but the flatMapping function receives a stream of elements and then performs an accumulation operation through the collector. First, let’s look at the model class:
class Blog { private String authorName; private List<String> comments = new ArrayList<>(); public Blog(String authorName, String ... comment){ this.authorName = authorName; comments.addAll(Arrays.asList(comment)); } public String getAuthorName(){ return this.authorName; } public List<String> getComments(){ return comments; } }
Collectors.flatMapping method skips the intermediate collection and writes directly to a single group mapping container defined by 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 maps all groups (Author's comment) Values are collected in a container, such as a List. And delete the intermediate collection and store the collection directly into the collector's container.
The above is the detailed content of How to use the new features of Java9 Stream Collectors. For more information, please follow other related articles on the PHP Chinese website!