Java 8 Streams - Grouping into Single value
Collectors.toMap()
does exactly what you're looking to do.
Map<Object, Map<String, Object>> collect = maps.stream()
.collect(Collectors.toMap(p -> p.get("reference"), Function.identity()));
Output:
{
PersonX={firstname=Person, reference=PersonX, lastname=x, dob=test},
JohnBartlett={firstname=John, reference=JohnBartlett, lastname=Bartlett, dob=test}
}
This will throw an IllegalStateException
if you have a duplicate key, which is probably exactly what you want when you never expect there to be a duplicate record in your data:
Exception in thread "main" java.lang.IllegalStateException: Duplicate key JohnBartlett (attempted merging values {dob=test, lastname=Bartlett, reference=JohnBartlett, firstname=John} and {dob=test 2, lastname=Bartlett, reference=JohnBartlett, firstname=John})
at java.base/java.util.stream.Collectors.duplicateKeyException(Collectors.java:133)
at java.base/java.util.stream.Collectors.lambda$uniqKeysMapAccumulator$1(Collectors.java:180)
at java.base/java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
at java.base/java.util.AbstractList$RandomAccessSpliterator.forEachRemaining(AbstractList.java:720)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
at so.UniqueKeyStreamExample.main(UniqueKeyStreamExample.java:22)
If I understood correctly, then for the cases where you are sure that there is a single item, you should just replace:
.collect(Collectors.groupingBy(
item -> item.get("key1"),
Collectors.toMap(item -> item.get("key2"), Function.identity())
));
You can even provide a third argument as a BinaryOperator
to merge your same entries (in case you need to)