Подтвердить что ты не робот

Преобразование массива String в Map с использованием Java 8 Лямбда-выражения

Есть ли лучший функциональный способ преобразования массива строк в форме "ключ: значение" в Map с использованием синтаксиса лямбда Java 8?

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

Решение, которое я имею прямо сейчас, не выглядит действительно функциональным:

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

Ответ 1

Вы можете изменить свое решение, чтобы собрать Stream из String массивов в 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]));

Конечно, это решение не защищает от недопустимого ввода. Возможно, вы должны добавить фильтр на случай, если разделительная строка не имеет разделителя:

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

Это по-прежнему не защищает вас от всех недопустимых входов (например, "c:3r" приведет к тому, что NumberFormatException будет выбрано parseDouble).

Ответ 2

Частичный ответ, поскольку вы ищете улучшения:

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

Сообщение об ошибках с потоком кажется сложным.

Конструктор карт может иметь большее значение, если "a", 1.0 допустимы.