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

Как конвертировать список в карту с индексами с использованием потока - Java 8?

Я создал метод, который перечисляет каждый символ алфавита. Я изучаю потоки (функциональное программирование) и стараюсь использовать их как можно чаще, но я не знаю, как это сделать в этом случае:

private Map<Character, Integer> numerateAlphabet(List<Character> alphabet) {
    Map<Character, Integer> m = new HashMap<>();
    for (int i = 0; i < alphabet.size(); i++)
        m.put(alphabet.get(i), i);
    return m;
}

Итак, как переписать его с помощью потоков Java 8?

4b9b3361

Ответ 1

Избегайте счетчиков индекса состояния, таких как решения на основе AtomicInteger, представленные в других ответах. Они потерпят неудачу, если поток будет параллельным. Вместо этого перейдите по индексам:

IntStream.range(0, alphabet.size())
         .boxed()
         .collect(toMap(alphabet::get, i -> i));

Выше предполагается, что входящий список не должен иметь повторяющиеся символы, так как он является алфавитом. Если у вас есть возможность дублировать элементы, то несколько элементов будут сопоставляться с одним и тем же ключом, а затем вам нужно указать функцию слияния. Например, вы можете использовать (a,b) -> b или (a,b) ->a в качестве третьего параметра для метода toMap.

Ответ 2

+1 для решения, предложенного Мишей.

Еще одно предложение: лучше использовать Function.identity() вместо i->i:

IntStream.range(0, alphabet.size())
                .boxed()
                .collect(toMap(alphabet::get, Function.identity()));

Ответ 3

Использование потоков с AtomicInteger в Java 8:

private Map<Character, Integer> numerateAlphabet(List<Character> alphabet) {
    AtomicInteger index = new AtomicInteger();
    return alphabet.stream().collect(
            Collectors.toMap(s -> s, s -> index.getAndIncrement(), (oldV, newV)->newV));
}

Ответ 4

с помощью AtomicInteger

    AtomicInteger counter = new AtomicInteger();
    Map<Character, Integer> map = characters.stream()
            .collect(Collectors.toMap((c) -> c, (c) -> counter.incrementAndGet()));
    System.out.println(map);

Ответ 5

Используя Collectors, он прост как:

alphabet.stream().collect(Collectors.toMap(i -> i, i -> alphabet.indexOf(i)));