How to produce map with distinct values from a map (and use the right key using BinaryOperator)?
You can use Collectors.toMap
private Map<Integer, String> deduplicateValues(Map<Integer, String> map) {
Map<String, Integer> inverse = map.entrySet().stream().collect(toMap(
Map.Entry::getValue,
Map.Entry::getKey,
Math::max) // take the highest key on duplicate values
);
return inverse.entrySet().stream().collect(toMap(Map.Entry::getValue, Map.Entry::getKey));
}
Try this: Simple way is inverse the key and value then use toMap()
collector with merge function.
map.entrySet().stream()
.map(entry -> new AbstractMap.SimpleEntry<>(entry.getValue(), entry.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, reducingKeysBinaryOperator));
Map<K, V> output = map.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey, reducingKeysBinaryOperator))
.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
I find the non-streams solution more expressive:
BinaryOperator<K> reducingKeysBinaryOperator = (k1, k2) -> k1 > k2 ? k1 : k2;
Map<V, K> reverse = new LinkedHashMap<>(map.size());
map.forEach((k, v) -> reverse.merge(v, k, reducingKeysBinaryOperator));
Map<K, V> result = new LinkedHashMap<>(reverse.size());
reverse.forEach((v, k) -> result.put(k, v));
This uses Map.merge
with your reducing bi-function and uses LinkedHashMap
to preserve original entries order.