我有一张地图Map<K, V>
,我的目标是删除重复的值并Map<K, V>
再次输出相同的结构。如果发现重复的值,则必须k
从两个键(k1
和k1
)中选择一个保存这些值的键(),因此,假定BinaryOperator<K>
提供k
了k1
并k2
可用。
输入和输出示例:
// Input
Map<Integer, String> map = new HashMap<>();
map.put(1, "apple");
map.put(5, "apple");
map.put(4, "orange");
map.put(3, "apple");
map.put(2, "orange");
// Output: {5=apple, 4=orange} // the key is the largest possible
用我的尝试Stream::collect(Supplier, BiConsumer, BiConsumer)
是位非常笨拙,包含可变操作,比如Map::put
和Map::remove
我想避免:
// // the key is the largest integer possible (following the example above)
final BinaryOperator<K> reducingKeysBinaryOperator = (k1, k2) -> k1 > k2 ? k1 : k2;
Map<K, V> distinctValuesMap = map.entrySet().stream().collect(
HashMap::new, // A new map to return (supplier)
(map, entry) -> { // Accumulator
final K key = entry.getKey();
final V value = entry.getValue();
final Entry<K, V> editedEntry = Optional.of(map) // New edited Value
.filter(HashMap::isEmpty)
.map(m -> new SimpleEntry<>(key, value)) // If a first entry, use it
.orElseGet(() -> map.entrySet() // otherwise check for a duplicate
.stream()
.filter(e -> value.equals(e.getValue()))
.findFirst()
.map(e -> new SimpleEntry<>( // .. if found, replace
reducingKeysBinaryOperator.apply(e.getKey(), key),
map.remove(e.getKey())))
.orElse(new SimpleEntry<>(key, value))); // .. or else leave
map.put(editedEntry.getKey(), editedEntry.getValue()); // put it to the map
},
(m1, m2) -> {} // Combiner
);
是否有一个解决方案可以Collectors
在一个Stream::collect
调用中使用适当的组合(例如,没有可变操作)?
如果相同的值与2个键相关联,如何选择保留哪个键?
—
迈克尔
您的情况下的预期输出是多少?
—
YCF_L
@ Turing85:正如我所说。该更好或最好是没有明确使用可变映射方法,如
—
Nikolas
Map::put
或Map::remove
内Collector
。
值得一看
—
Naman
BiMap
。可能是从Java中的HashMap中删除重复值
Stream
s 完成?