Как преобразовать карту <K, V1> в другую карту <K, V2> с помощью карты функций в Java 8?
Я хочу преобразовать Map<String, Integer>
в другой Map<String, Long>
с помощью карты функций в Java 8, сопоставляя данные с функциями с помощью ключа на обеих картах. Вы можете предположить, что обе карты имеют одинаковые ключи.
Я попробовал следующий подход:
Map<String, Integer> inputData = new HashMap<>();
inputData.put("A",8);
inputData.put("B",7);
inputData.put("C",6);
Map<String, Function<Integer, Long>> transformers = new HashMap<>();
transformers.put("A", x -> x*2L);
transformers.put("B", x -> x+3L);
transformers.put("C", x -> x+11L);
Map<String, Long> mappedData = inputData.entrySet().stream()
.map(entry -> new AbstractMap.SimpleEntry<>(
entry.getKey(),
transformers.get(entry.getKey()).apply(entry.getValue())))
.collect(toMap(Map.Entry::getKey, Map.Entry::getValue));
Ожидаемый результат: {A = 16, B = 10, C = 17}.
Есть ли более простой способ выражения "применить карту трансформаторов к отображению соответствия ввода данных по ключу" в API Java Streams?
Ответы
Ответ 1
Вы можете напрямую преобразовать в сборщик:
Map<String, Long> mappedData = inputData.entrySet().stream()
.collect(toMap(Map.Entry::getKey,
entry -> transformers.get(entry.getKey()).apply(entry.getValue())));
Такое решение короче и не создает промежуточные объекты.
Если ваш inputData
имел тот же тип значения (Map<String, Long>
), вы могли бы выполнить преобразование на месте:
inputData.replaceAll((key, value) -> transformers.get(key).apply(value));
Ответ 2
Вы также можете начать с самой карты transformers
, которая выглядит несколько проще:
Map<String, Long> collect = transformers.entrySet().stream()
.collect(toMap(Map.Entry::getKey,
e -> e.getValue().apply(inputData.get(e.getKey()))));
Ответ 3
Если одна дополнительная строка вас не беспокоит, попробуйте
Map<String, Long> result = new HashMap<>(); // this line
inputData.forEach((k, v) -> result.put(k, transformers.get(k).apply(v));