Convert String array to Map using Java 8 Lambda ex

2019-01-23 11:12发布

Is there a better functional way of converting an array of Strings in the form of "key:value" to a Map using the Java 8 lambda syntax?

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

The solution I have right now does not seem really functional:

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])));

2条回答
男人必须洒脱
2楼-- · 2019-01-23 11:47

Partial answer, as you are looking for improvements:

Stream.of("a:1.0", "b:2.0", "c:3.0")
    .map(...)
    ...

Error reporting with a stream seems difficult.

A map builder might make more sence, if "a", 1.0 were allowable.

查看更多
姐就是有狂的资本
3楼-- · 2019-01-23 12:04

You can modify your solution to collect the Stream of String arrays into a Map (instead of using 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]));

Of course this solution has no protection against invalid input. Perhaps you should add a filter just in case the split String has no separator :

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]));

This still doesn't protect you against all invalid inputs (for example "c:3r" would cause NumberFormatException to be thrown by parseDouble).

查看更多
登录 后发表回答