Reputation: 45
I'm recently learning about Java stream and try to practice some of stream features by converting some of my previous code snippet. The following traditional for loop in the program is to store the index and its reversed string in the original array to a map.
String[] words = {"hey", "there", "how", "are", "you"};
Map<String, Integer> map = new HashMap<>();
for (int i = 0; i < words.length; i++) {
String rev = new StringBuilder(words[i]).reverse().toString();
map.put(rev, i);
}
However, I have a hard time achieving this same thing using pure stream. I think the problem I have is how to keep track of the index and the reversed string at the same time. As you can see from the traditional for loop, I'm converting the string to stringbuilder, then reverse it, and then convert back to string. Finally I put index and string to map. But I couldn't figure out a way to keep track of all these using pure stream. Somebody could enlighten me? Thanks!
Upvotes: 0
Views: 882
Reputation: 40034
As you are learning about streams I offer this alternative Collectors.toMap
method. It allows you to use a merge function
and specify a type of map
. In this case the merge function is not used but by using a LinkedHashMap
, the order of the map is preserved.
Map<String, Integer> map =
IntStream.range(0, words.length).boxed()
.collect(Collectors.toMap(
i -> new StringBuilder(words[i])
.reverse().toString(),
i -> i,
// merge is unused
(r, s) -> s,
// supplier for the type of map
LinkedHashMap::new));
System.out.println(map);
Prints
{yeh=0, ereht=1, woh=2, era=3, uoy=4}
Upvotes: 0
Reputation: 19545
It can be done via IntStream which imitates for
loop:
Map<String, Integer> map = IntStream.range(0, words.length).boxed()
.collect(Collectors.toMap(
i -> new StringBuilder(words[i]).reverse().toString(), // key: reversed string
i -> i // value: index in array
));
Upvotes: 3