如何使用Java 8中的函数映射将Map<K,V1>转换为另一个Map<K,V2>?

2022-09-03 06:12:13

我想使用Java 8中的函数映射将a转换为另一个,通过两个映射中的键将数据与函数相匹配。您可以假定两个映射具有相同的键。Map<String, Integer>Map<String, Long>

我尝试了以下方法:

Map<String, Integer> inputData = new HashMap<>();
inputData.put("A",8);
inputData.put("B",7);
inputData.put("C",6);

Map<String, Function<Integer, Long>> transformers = new HashMap<>();
transformers.put("A", x -> x*2L);
transformers.put("B", x -> x+3L);
transformers.put("C", x -> x+11L);

Map<String, Long> mappedData = inputData.entrySet().stream()
    .map(entry -> new AbstractMap.SimpleEntry<>(
         entry.getKey(),
         transformers.get(entry.getKey()).apply(entry.getValue())))
    .collect(toMap(Map.Entry::getKey, Map.Entry::getValue));

预期结果:{A=16,B=10,C=17}。

在 Java Streams API 中,有没有更简单的方法来表达“将转换器的映射应用于输入数据匹配的映射”?


答案 1

您可以直接在收集器中进行转换:

Map<String, Long> mappedData = inputData.entrySet().stream()
    .collect(toMap(Map.Entry::getKey, 
            entry -> transformers.get(entry.getKey()).apply(entry.getValue())));

这样的解决方案更短,并且不会创建中间对象。

如果具有相同的值类型 (),则可以就地执行转换:inputDataMap<String, Long>

inputData.replaceAll((key, value) -> transformers.get(key).apply(value));

答案 2

您也可以从地图本身开始,这看起来稍微容易一些:transformers

    Map<String, Long> collect = transformers.entrySet().stream()
            .collect(toMap(Map.Entry::getKey, 
                    e -> e.getValue().apply(inputData.get(e.getKey()))));

推荐