Расширение карты коллекций до одномерной карты новое «Не удается определить тип функционального интерфейса»

#java

#java

Вопрос:

У меня есть некоторые значения на карте, которые я хотел бы преобразовать в более простую карту, где будет ключ 'A' -> 1, 'E'-> 1,...'Z'-> 10 . Продолжайте получать «Не удается определить тип функционального интерфейса».

 private Map<List<Character>, Integer> scoresMap
        = Map.of(
        List.of('A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T'), 1,
        List.of('D', 'G'), 2,
        List.of('B', 'C', 'M', 'P'), 3,
        List.of('F', 'H', 'V', 'W', 'Y'), 4,
        List.of('K'), 5,
        List.of('J', 'X'), 8,
        List.of('Q', 'Z'), 10
);
 

Я попробовал функциональный подход:

 private Stream<Map.Entry<Character, Integer>> expandMap(Map.Entry<List<Character>, Integer> kv){
    return kv.getKey()
            .stream()
            .collect(
                    Stream.of(),
                    (Stream<Map.Entry<Character, Integer>> acc, char el) ->
                            Stream.concat(acc, Stream.of(Map.entry(el, kv.getValue()))),
                    (Stream<Map.Entry<Character, Integer>> acc, Stream<Map.Entry<Character, Integer>> el) -> Stream.concat(acc, el)
                    );

}
 

И попробовал forEach:

 private Map<Character, Integer> scores(){
    Map<Character, Integer> scores = Map.of();
    scoresMap
    .entrySet()
    .forEach(
        (Map.Entry<List<Character>, Integer> kv) -> 
            kv.getKey().forEach(
                    (char k) ->
                            scores.put(k, kv.getValue());
                )
        )
    
    return scores;
 

}

Я думаю, что это не связано с неоднозначными типами, поскольку я пытался использовать маленькие помощники вместо лямбд.

Ответ №1:

Вы можете использовать flatMap :

 Map<Character, Integer> simpleMap = scoresMap.entrySet()
            .stream()
            .flatMap(entry -> {
                Integer value = entry.getValue();
                return entry.getKey().stream().map(ch -> Map.entry(ch, value));
            })
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
 

Комментарии:

1. Плоская карта — это то, что мне нужно, чтобы перейти от списка символов к символу. Функциональная Java обладает множеством функций, если вы знаете, где искать. Синтаксис не самый простой для понимания. Я ходил по домам, пытаясь понять коллекционеров. Я думаю, что эта сложность связана с тем, что выполнение не всегда является последовательным.

Ответ №2:

Вы можете использовать Map.forEach() напрямую, и вам не нужно беспокоиться о типах, Java может вычислить это сама.

 private Map<Character, Integer> scores(){

    Map<Character, Integer> scores = new HashMap<>();

    scoresMap.forEach((key, value) -> 
            key.forEach((k) ->
                scores.put(k, value)));

    return scores;
}