我知道如何“转换”一个简单的Java列表从Y -> Z,即:

List<String> x;
List<Integer> y = x.stream()
        .map(s -> Integer.parseInt(s))
        .collect(Collectors.toList());

现在我想对Map做基本相同的事情,即:

INPUT:
{
  "key1" -> "41",    // "41" and "42"
  "key2" -> "42"      // are Strings
}

OUTPUT:
{
  "key1" -> 41,      // 41 and 42
  "key2" -> 42       // are Integers
}

解决方案不应局限于String -> Integer。就像上面的List示例一样,我想调用任何方法(或构造函数)。


当前回答

声明式的、更简单的Java8+解决方案是:

yourMap。补充((钥匙,瓦尔)->电脑瓦尔);

向: http://www.deadcoderising.com/2017-02-14-java-8-declarative-ways-of-modifying-a-map-using-compute-merge-and-replace/

其他回答

它一定要100%的功能性和流畅性吗?如果没有,那么下面这个怎么样,它是最简短的:

Map<String, Integer> output = new HashMap<>();
input.forEach((k, v) -> output.put(k, Integer.valueOf(v));

(如果你能忍受将流和副作用结合在一起的羞耻和内疚的话)

声明式的、更简单的Java8+解决方案是:

yourMap。补充((钥匙,瓦尔)->电脑瓦尔);

向: http://www.deadcoderising.com/2017-02-14-java-8-declarative-ways-of-modifying-a-map-using-compute-merge-and-replace/

Map<String, String> x;
Map<String, Integer> y =
    x.entrySet().stream()
        .collect(Collectors.toMap(
            e -> e.getKey(),
            e -> Integer.parseInt(e.getValue())
        ));

它不像列表代码那么好。你不能构造新的地图。映射到map()调用中,因此工作被混合到collect()调用中。

如果你不介意使用第三方库,我的cyclops-react库有所有JDK集合类型的扩展,包括Map。我们可以直接使用'map'操作符转换map(默认情况下map作用于map中的值)。

   MapX<String,Integer> y = MapX.fromMap(HashMaps.of("hello","1"))
                                .map(Integer::parseInt);

Bimap可用于同时转换键和值

  MapX<String,Integer> y = MapX.fromMap(HashMaps.of("hello","1"))
                               .bimap(this::newKey,Integer::parseInt);

我的StreamEx库增强了标准流API,提供了一个EntryStream类,更适合转换地图:

Map<String, Integer> output = EntryStream.of(input).mapValues(Integer::valueOf).toMap();