Skip to content
Advertisement

Java Streams – group-by and return a Nested Map

my data is like this,

JavaScript

my goal is put every unitId and value into a map like this,

JavaScript

I already figure out two ways to achieve that, here is my code,

JavaScript

and,

JavaScript

First one more like write the processing manually, second one uses temporary lists which may not be necessary. Is there any direct or simple way to do this, like use Collectors.toMap API or something else?

Advertisement

Answer

Is there any direct or simple way to do this, like use Collectors.toMap API or something else?

If you want to utilize only built-in collectors, you might try a combination of groupingBy() and teeing().

Collectors.teeing() expects three arguments: 2 downstream collectors and a merger function. Each element from the stream will be passed into both collectors, and when these collectors are done, results produced by them will get merged by the function.

In the code below, toMap() is used as both downstream collectors of teeing(). And each of these collectors is responsible for retrieving its type of value.

The code might look like that:

JavaScript

Output:

JavaScript

Note:

  • If performance is concerned, Collector.of() would be slightly better because it doesn’t create intermediate collections.
  • For this approach to work correctly (I mean the code listed above as well as in the question), each combination of unitId and year should be unique. Otherwise, consider adding a logic for resolving duplicates.
Advertisement