Java 8:更改条目类型返回Map

时间:2018-01-11 15:28:06

标签: java java-8 java-stream

我遇到了以下问题: 我有一个Map<?,?>,我从PList文件中解析它,简化如下:

Map<String, String> m  = (Map<String, String>) getMap();

getMap()方法只读取文件(.plist)。 我想将所有值解析为String,但遗憾的是Map包含整数,导致过程中出现错误。 所以我想编写一个使用过滤器将一切转换为String的方法:

我的方法是:

m.entrySet().stream()
    .map(e -> e.getValue())
    .filter(e -> e instanceof Integer)
    .map(e -> String.valueOf(e))
    .collect(Collectors.toMap(e -> e.keys(), e -> e.getValue()));

问题是,最后的收集不起作用,我该如何解决这个问题? 结果应该是一张地图。

非常感谢你!

4 个答案:

答案 0 :(得分:4)

你误解了Collectors.toMap的工作方式 - 它需要两个函数,一个给一个条目产生一个新的密钥,一个给一个条目产生一个新的值。然后,映射中的每个条目都应用了这两个函数,并且该单个元素的结果键/值用于在新映射中构造新条目。

此外,通过将每个条目映射到该值,您将失去键和值之间的关联,这意味着您无法正确地重建地图。

更正版本将是:

Map<String, String> n;
n = m.entrySet()
     .stream()
     .filter(e -> e.getValue() instanceof Integer)
     .collect(Collectors.toMap(e -> e.getKey(),
                               e -> String.valueOf(e.getValue())));

答案 1 :(得分:2)

您的代码中有一些错误。

首先,当您将每个条目映射到其值时,您将丢失密钥。

然后,当您进行过滤时,您只在流中保留Integer个值,这将产生不完整的地图。

最后,在Collectors.toMap您使用e.keys()e.getValue,这是不正确的,因为e.keys()既不是Map.Entry也不String的方法1}},因为您需要使用e.getValue()代替e.getValue

代码应如下:

m.entrySet().stream().collect(Collectors.toMap(
    e -> e.getKey(), 
    e -> e.getValue() instanceof Integer ?
        String.valueOf(e.getValue()) : 
        e.getValue()));

答案 2 :(得分:2)

replaceAll方法可能更适合这种情况。它可以像:

一样使用
m.replaceAll((k, v) -> String.valueOf(v));

答案 3 :(得分:1)

Map<String, String> m2 = m.entrySet().stream()
    .collect(Collectors.toMap(e -> Objects.toString(e.getKey()),
                              e -> Objects.toString(e.getValue())));

这将通过toString将键和值都转换为字符串。 null(值)将变为&#34; null&#34;。