Java 8 GroupingBy at Peek

I recently learned about threads in Java 8 and started working with them. Now I have a question regarding the groupingBy collector method:

I usually work with .NET, so I compared (knowing that they are not the same) Java Stream<T> with .NET IEnumerable<T> . After this comparison, List<T> stores the elements, and specific Stream / IEnumerable apply operations. One example:

FROM#:

 elements.Where(x => x.Value == 5).ToList(); 

Java:

 elements.stream().filter(x -> x.getValue() == 5).collect(Collectors.toList()); 

In both examples, I start with a list, define operations (filter in this example), and collect the result to save it (in a new list in this example).

Now I got a more complicated case:

 data.stream() .map( ... ).filter( ... ) // Some operations .collect(groupingBy(Chunk::getName, summingLong(Chunk::getValue))); 

The result of this query is Map<String, Long> , and I can work with it, but, say, I want to continue this data, and not store it. My current approach is trivial:

  ... .collect(groupingBy(Chunk::getName, summingLong(Chunk::getValue))) .entrySet().stream(). .map( ... ) // Do more operations 

But in this way I leave the stream, save the first result on the map and open a new stream to continue. Is there a way to group without a collector so that I can "stay" in the stream?

+6
source share
2 answers

As an API now, you cannot avoid this.

groupingBy

is a terminal operation (it does not return a stream), so the operation will terminate the stream.

Depending on what you want to do later in the last card operation, you can create a custom collector that will โ€œstayโ€ inside the stream; even if inside you are likely to still collect elements on the map.

+4
source

You can do whatever you want in the downstream collector if you can describe the operation as Collector . Currently, there is only the equivalent of the intermediate map operation, the mapping collector, but Java 9 will also add filtering and flatMapping (which you can also implement yourself in Java 8), and theres are already equivalent to almost every terminal operation.

Of course, the nested collectors device will look completely different than the chain of Stream operations doing the same thing ...

If, however, you want to process full groups, you do not first need to assemble a grouping collection. This is not a limitation of the API, but is an integral part of the grouping operation or any operation as a whole, if you want to process the full result, you need to perform the operation first. No matter what the API looks like, for example. you can hide the subsequent operation in the collector in collectingAndThen similar way, creating and populating a map inevitable, like its map supporting groups. Groups are defined by the keys and map search logic, so, for example, using SortedMap with a custom comparator or IdentityHashMap can completely change the grouping logic.

+5
source

Source: https://habr.com/ru/post/1013909/


All Articles