For example, for two classes like this:
Class RawItem {
private String category;
private int code;
private String name;
}
Class Item {
private int code;
private String name;
}
And list of RawItem as following:
[ { "category":"a", "code":1, "name":"item1" }, { "category":"a", "code":1, "name":"item1" }, { "category":"a", "code":2, "name":"item2" }, { "category":"b", "code":1, "name":"item1" }, { "category":"b", "code":1, "name":"item1" } ]
Turn it to a Map<String, List<Item>>
like this:
{
"a":[
{
"code":1,
"name":"item1"
},
{
"code":2,
"name":"item2"
}
],
"b":[
{
"code":1,
"name":"item1"
}
]
}
Any reply will be greatly appreciated. thanks.
The following groupingBy
should work.
As part of your additional requirements, we know that the equals
method of RawItem
objects cannot be used, which is why we are using a filter instead of the Stream
distinct
method (*):
Set<Object> seen = ConcurrentHashMap.newKeySet();
Map<String, List<Item>> m =
l.stream()
.filter(item -> seen.add(item.category + ":" + item.name + ":" + item.code))
.collect(Collectors.groupingBy(item -> item.category,
Collectors.mapping(item -> new Item(item.code, item.name),
Collectors.toList())));
Note that in order to allow the method distinct
to work and remove duplicates, you need to have a proper implementation of the hashCode
and equals
methods in the RawItem
class.
As an example, the following test:
List<RawItem> list = Arrays.asList(new RawItem("a", 1, "dfg"),
new RawItem("a", 1, "dfg"),
new RawItem("a", 1, "fdgdfdfgdg"),
new RawItem("b", 1, "dfg"));
Map<String, List<Item>> map = // the above
System.out.println(map);
gives
{
a=[Item{code=1, name='dfg'}, Item{code=1, name='fdgdfdfgdg'}],
b=[Item{code=1, name='dfg'}]
}
(*) Edit:
As shared by the OP, the following posts help to design a solution based on a custom equivalence relationship with the stream API, when distinct()
cannot be used: