I have the following for loop which I would like to replace by a simple Java 8 stream statement:
List<String> words = new ArrayList<>("a", "b", "c");
Map<String, Long> wordToNumber = new LinkedHashMap<>();
Long index = 1L;
for (String word : words) {
wordToNumber.put(word, index++);
}
I basically want a sorted map (by insertion order) of each word to its number (which is incremented at each for loop by 1), but done simpler, if possible with Java 8 streams.
The following should work (though it's not clear why Long
is needed because the size of List
is int
)
Map<String, Long> map = IntStream.range(0, words.size())
.boxed().collect(Collectors.toMap(words::get, Long::valueOf));
The code above works if there's no duplicate in the words
list.
If duplicate words are possible, a merge function needs to be provided to select which index should be stored in the map (first or last)
Map<String, Long> map = IntStream.range(0, words.size())
.boxed().collect(
Collectors.toMap(words::get, Long::valueOf,
(w1, w2) -> w2, // keep the index of the last word as in the initial code
LinkedHashMap::new // keep insertion order
));
Similarly, the map can be built by streaming words
and using external variable to increment the index (AtomicLong
and getAndIncrement()
may be used instead of long[]
):
long[] index = {1L};
Map<String, Long> map = words.stream()
.collect(
Collectors.toMap(word -> word, word -> index[0]++,
(w1, w2) -> w2, // keep the index of the last word
LinkedHashMap::new // keep insertion order
));