java之如何从 map 中生成具有不同值的 map (并使用 BinaryOperator 使用正确的键)

telwanggs 阅读:52 2024-05-29 10:23:45 评论:0

我有 map Map<K, V>我的目标是删除重复的值并输出相同的结构 Map<K, V>再次。如果发现重复值,则必须从保存这些值的两个键( kk1 )中选择一个键( k1 ),因此,假设 BinaryOperator<K>给予 k来自 k1k2可用。

示例输入和输出:

// 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::putMap::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调用(例如,没有可变操作)?

请您参考如下方法:

您可以使用 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)); 
} 


标签:java
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号