I have a java List
of CodeObj
. CodeObj
has 2 attributes : codeName
and version
.
My java List
looks like this when mapped to a JSON
object :
[
{ "codeName": "test1", "version": "1" },
{ "codeName": "test1", "version": "2" },
{ "codeName": "test1", "version": "3" },
{ "codeName": "test2", "version": "1" },
{ "codeName": "test2", "version": "2" },
{ "codeName": "test2", "version": "3" },
{ "codeName": "test2", "version": "4" },
]
I would like to filter this List
by each codeName
most recent version
in java, so it would give this result when mapped to a JSON object :
[
{ "codeName": "test1", "version": "3" },
{ "codeName": "test2", "version": "4" },
]
To make it, I have to use the Stream
java class and its methods like filter
, map
, max
, etc.
I started with this bit of code :
codeObjs.stream()
.max(Comparator.comparing(CodeObj::getVersion))
I feel like I have to isolate each set of CodeObj
that has the same codeName
, but I don't know how to do it while turning the List
into a Stream
.
return codeObjs.stream()
.collect(Collectors.groupingBy(
CodeObj::getCodeName,
Collectors.maxBy(Comparator.comparing(CodeObj::getVersion))
))
.values().stream()
.flatMap(Optional::stream)
.collect(Collectors.toList());
So, basically, you are isolating each instance of CodeObj
with a unique name by using Collectors.groupingBy
. Then using Collectors.maxBy
on each group, you get the highest version. Then, by streaming the resulting map, you access collections of Optional<CodeObj>
instances, which represent the highest versions per group. flatMap(Optional::stream)
transforms these Optionals
into a sequence of CodeObj
. Finally, you collect them into a list through Collectors.toList()