Как конвертировать список в карту с индексами с использованием потока - 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?
Ответы
Ответ 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)));