I have a piece of code that has list of objects as follows.
List<PivotMapEgModel> pivotMapList = List.of(new PivotMapEgModel(1L, "1"), new PivotMapEgModel(1L, "2"), new PivotMapEgModel(1L, "3"), new PivotMapEgModel(2L, "5"));
It is guaranteed that there will always be a maximum of 3 codes per value.
I have a class that looks like this:
@Data
@AllArgsConstructor
class ResultSet {
long value;
String code_1;
String code_2;
String code_3;
}
I am currently doing the stream operation in this way:
pivotMapList.stream().collect(Collectors.groupingBy(PivotMapEgModel::getValue, Collectors.mapping(PivotMapEgModel::getCode, Collectors.toList())))
This is producing the output in the following way: {1=[1, 2, 3], 2=[5]}
I need to perform stream operations on the pivotMapList to get the output to show in List<ResultSet>
as follows:
[{value=1, code_1=1, code_2=2, code_3=3},
{value=2, code_1=1, code_2=null, code_3=null}]
I am not sure how I can get List<ResultSet>
from stream operations
Any help to achieve the desired output would be greatly appreciated! Thank you
CodePudding user response:
You have already mapped value to its codes. You can just continue by streaming the entry set of the resulting map and map entries to ResultSet
.
List<ResultSet> result = pivotMapList.stream()
.collect(Collectors.groupingBy(PivotMapEgModel::getValue, Collectors.mapping(PivotMapEgModel::getCode, Collectors.toList())))
.entrySet()
.stream()
.map(entry -> new ResultSet(entry.getKey(), getCode(entry.getValue(), 0), getCode(entry.getValue(), 1), getCode(entry.getValue(), 2)))
.collect(Collectors.toList());
getCode()
is simple method taking care not to get exception when retrieving values from the list.
private static String getCode(List<String> codes, int index) {
if (index >= codes.size()) {
return null;
}
return codes.get(index);
}
CodePudding user response:
Here is one way.
class ResultSet {
long value;
String code_1;
String code_2;
String code_3;
public ResultSet(long value, String code_1,String code_2, String code_3) {
this.value = value;
this.code_1 = code_1;
this.code_2 = code_2;
this.code_3 = code_3;
}
public String toString() {
return "{%d, %s, %s, %s}".formatted(value, code_1, code_2, code_3);
}
}
Use your existing map to build the list. Stream the entrySet of the map and use map
to instantiate a ResultSet
instance. The forloop will fill the list with nulls if it isn't fully populated.
List<ResultSet> resultSet = map.entrySet().stream()
.<ResultSet>map(ent-> {
List<String> lst = ent.getValue();
for( int i = lst.size(); i < 3; i ) {
lst.add(null);
}
return new ResultSet(ent.getKey(), lst.get(0),
lst.get(1), lst.get(2));
}).toList();
resultSet.forEach(System.out::println);
prints
{1, 1, 2, 3}
{2, 5, null, null}
Note that you could simply stream the existing entrySet
from the original map to combine the process, returning the desired List<ResultSet>