I have the following HashMap in my Java app:
final Map<UUID, Boolean> map = demoRepo.demoService.stream()
.collect(Collectors.toMap(
ProductDTO::getMenuUuid,
ProductDTO::getStatus));
However, as the result contains multiple menuUuid
value, I need to group them as the key does not contain the same value. So, how should I do this using stream?
Update: I also tried groupingBy
as shown below, but I think the usage is not correct:
final Map<UUID, Boolean> map = sdemoRepo.demoService.stream()
.collect(Collectors.groupingBy(
ProductDTO::getMenuUuid, LinkedHashMap::new,
Collectors.mapping(ProductDTO::getStatus)));
Suppose that I have the following stream:
MenuUuid | Status |
-----------------------
1 true
2 false
1 true
1 true
3 true
2 false
Then I need a map result like; 1:true, 2:false, 3:true
CodePudding user response:
If all the user ids have the same boolean then just do the following:
final Map<UUID, Boolean> map = demoRepo.demoService.stream()
.collect(Collectors.toMap(
ProductDTO::getMenuUuid,
ProductDTO::getStatus,
(existingValue, newValue)->existingValue));
the last lambda, is a merge function. it is used to make a decision on how to merge duplicate keys. In this case, it just keeps the first that's already there. You could also use the new one since you aren't really altering the boolean
and they are all the same value.
If your ProductDTO
class uses UUID
to determine equality via equals()
you could also do the following:
final Map<UUID, Boolean> map = demoRepo.demoService.stream()
.distinct()
.collect(Collectors.toMap(
ProductDTO::getMenuUuid,
ProductDTO::getStatus));
This works because you won't have any duplicate UUID's
CodePudding user response:
The Collectors.toMap(Function keyMapper, Function valueMapper, BinaryOperator mergeFunction) allows the caller to define a BinaryOperator mergeFunction that returns the correct value if the stream provides a key-value pair for a key that already exists.
The following example uses the Boolean.logicalOr method to combine the existing value with the new one. Equal UUID keys are not grouped,since the result is a single key-single value map. But
final Map<UUID, Boolean> map = demoRepo.demoService.stream()
.collect(Collectors.toMap(
ProductDTO::getMenuUuid,
ProductDTO::getStatus,
Boolean::logicalOr));
In particular Boolean::logicalOr
is a function that is called if the map already contains a value for the key. In this case, the Boolean::logicalOr takes as argument the existing map value and the new value from the
Stream` and returns the Logical Or of these two, as the result. This results is then entered in the map.
CodePudding user response:
You will have to merge the values. See if it helps
final Map<UUID, Boolean> map =
demoRepo.stream().filter(Objects::nonNull)
.collect(
Collectors.toMap(
ProductDTO::getMenuUuid,
ProductDTO::getStatus,
(menuUuid, status) -> {
menuUuid.addAll(status);
return menuUuid;
}));