J'ai créé une méthode qui numérote chaque caractère de l'alphabet. J'apprends les flux (programmation fonctionnelle) et essaie de les utiliser aussi souvent que possible, mais je ne sais pas comment faire dans ce cas:
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;
}
Alors, comment le réécrire en utilisant les flux de Java 8?
Évitez les compteurs d'index avec état comme les solutions basées sur AtomicInteger
présentées dans d'autres réponses. Ils échoueront si le flux était parallèle. Au lieu de cela, diffuser sur les index:
IntStream.range(0, alphabet.size())
.boxed()
.collect(toMap(alphabet::get, i -> i));
Ci-dessus suppose que la liste entrante n'est pas supposée avoir des caractères en double car c'est un alphabet. Si vous avez la possibilité de dupliquer des éléments, plusieurs éléments seront mappés sur la même clé et vous devrez ensuite spécifier la fonction merge . Par exemple, vous pouvez utiliser (a,b) -> b
ou (a,b) ->a
comme troisième paramètre de la méthode toMap
.
Il est préférable d'utiliser Function.identity()
à la place de i->i
:
IntStream.range(0, alphabet.size())
.boxed()
.collect(toMap(alphabet::get, Function.identity()));
Utilisation de flux avec AtomicInteger
en 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));
}
en utilisant AtomicInteger
AtomicInteger counter = new AtomicInteger();
Map<Character, Integer> map = characters.stream()
.collect(Collectors.toMap((c) -> c, (c) -> counter.incrementAndGet()));
System.out.println(map);