'Java stream: Grouping HashMap key values to prevent duplicate keys
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
Solution 1:[1]
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.
Solution 2:[2]
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;
}));
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Alagu Narayanan K |
