Reputation: 9509
I have a Map<String, List<StartingMaterial>>
I want to convert the Object in the List to another Object.
ie. Map<String, List<StartingMaterialResponse>>
Can I do this using java stream Collectors.toMap()?
I tried something like the below code.
Map<String, List<StartingMaterial>> startingMaterialMap = xxxx;
startingMaterialMap.entrySet().stream().collect(Collectors.toMap( Map.Entry::getKey, Function.identity(), (k, v) -> convertStartingMaterialToDto(v.getValue())));
And my conversion code to change the Object is like below,
private StartingMaterialResponse convertStartingMaterialToDto(StartingMaterial sm) {
final StartingMaterialMatrix smm = sm.getStartingMaterialMatrix();
final StartingMaterial blending1Matrix = smm.getBlending1Matrix();
final StartingMaterial blending2Matrix = smm.getBlending2Matrix();
return new StartingMaterialResponse(
sm.getId(),
sm.getComponent().getCasNumber(),
sm.getDescription(),
sm.getPriority(),
String.join(" : ",
Arrays.asList(smm.getCarryInMatrix().getComponent().getMolecularFormula(),
blending1Matrix != null ? blending1Matrix.getComponent().getMolecularFormula() : "",
blending2Matrix != null ? blending2Matrix.getComponent().getMolecularFormula() : ""
).stream().distinct().filter(m -> !m.equals("")).collect(Collectors.toList())),
smm.getFamily(),
smm.getSplitGroup());
}
Upvotes: 2
Views: 10490
Reputation: 1869
Here is my approach to this problem :
Map<String, List<Integer>> deposits = new HashMap<>();
deposits.put("first", Arrays.asList(1, 2, 3));
deposits.forEach((depositName, products) -> {
products.stream()
.map(myIntegerProduct -> myIntegerProduct.toString())
.collect(Collectors.toList());
});
The above example convert the List<Integer>
to a list of Strings.
In your example, instead of myIntegerProduct.toString()
is the convertStartingMaterialToDto
method.
The forEach
method iterates through every Key-Value pair in the map and you set some names for the key and the value parameters to be more specific and keep an understandable code for everyone who reads it. In my example : forEach( (depositName, products)) ->
the depositName is the Key ( in my case a String ) and the products is the Value of the key ( in my case is a List of integers ).
Finally you iterate through the list too and map
every item to a new type
products.stream()
.map(myIntegerProduct -> myIntegerProduct.toString())
Upvotes: 1
Reputation: 60045
I think you mean to do :
startingMaterialMap.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey,
e -> e.getValue().stream()
.map(this::convertStartingMaterialToDto)
.collect(Collectors.toList()))
);
Upvotes: 1
Reputation: 21124
You can use the toMap collector since your source is a map. However you have to iterate over all the values and convert each of them into the DTO format inside the valueMapper.
Map<String, List<StartingMaterialResponse>> result = startingMaterialMap.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().stream()
.map(s -> convertStartingMaterialToDto(s)).collect(Collectors.toList())));
Upvotes: 2