使用Java 8 Lambda表达式将String数组转换为Map

bsa*_*sam 32 java lambda functional-programming java-8 java-stream

是否有更好的功能方式将"key:value"形式的字符串数组转换为Map使用Java 8 lambda语法?

Arrays.asList("a:1.0", "b:2.0", "c:3.0")
        .stream()
        .map(elem -> elem.split(":")
        .collect(Collectors.toMap(keyMapper?, valueMapper?));
Run Code Online (Sandbox Code Playgroud)

我现在的解决方案似乎没有真正的功能:

Map<String, Double> kvs = new HashMap<>();
Arrays.asList("a:1.0", "b:2.0", "c:3.0")
        .stream()
        .map(elem -> elem.split(":"))
        .forEach(elem -> kvs.put(elem[0], Double.parseDouble(elem[1])));
Run Code Online (Sandbox Code Playgroud)

Era*_*ran 54

您可以修改您的解决方案收集StreamString数组到一个Map(而不是使用forEach):

Map<String, Double> kvs =
    Arrays.asList("a:1.0", "b:2.0", "c:3.0")
        .stream()
        .map(elem -> elem.split(":"))
        .collect(Collectors.toMap(e -> e[0], e -> Double.parseDouble(e[1]));
Run Code Online (Sandbox Code Playgroud)

当然,此解决方案无法防止无效输入.也许您应该添加一个过滤器,以防分裂String没有分隔符:

Map<String, Double> kvs =
    Arrays.asList("a:1.0", "b:2.0", "c:3.0")
        .stream()
        .map(elem -> elem.split(":"))
        .filter(elem -> elem.length==2)
        .collect(Collectors.toMap(e -> e[0], e -> Double.parseDouble(e[1]));
Run Code Online (Sandbox Code Playgroud)

这仍然无法保护您免受所有无效输入的影响(例如,"c:3r"会导致NumberFormatException被抛出parseDouble).

  • 我不认为默默地忽略错误的输入是一个很好的建议,这不是OP的要求.我最好使用`elem - > elem.split(":",2)`而不是添加`filter`步骤.这样,错误的输入将由`ArrayIndexOutOfBoundsException`(如果没有找到冒号)或`NumberFormatException`(如果找到多个冒号)表现出来. (6认同)