I need to collect a sentence to a map using stream, where the key is a character (the order should be like this: the first letter in the sentence is the first in the map, so I choose LinkedHashMap ), and the value is counter which shows the frequency of repeating the same character.
Example input: hello world
Example output: h=1, e=1, l=3, o=2, w=1, r=1, d=1
There is my code, and I can`t understand what is the problem.
private Map<Character, Integer> countSymbols(String sentence) {
return sentence.chars()
.collect(Collectors.toMap(key -> (Character) key,
counter -> 1,
Integer::sum,
LinkedHashMap::new));
}
String.chars()
returns an IntStream
(ie, a stream of primitieve int
s), that can't be collected with Collectors.toMap
.
You could map it to a Character
object, and once you've done so, you could use Collectors.grouping
to do the heavy lifting instead of implementing its logic:
private Map<Character, Long> countSymbols(String sentence) {
return sentence.chars()
.mapToObj(c -> (char) c)
.collect(Collectors.groupingBy(Function.identity(),
Collectors.counting()));
}
EDIT:
Collectors.grouping
does not retain the order of the stream, so you'll really have to implement it manually as you've done. the mapToObj
call is still required, and if you want to avoid counting the space between "hello" and "world" in the example, you need to add a filter
call:
private Map<Character, Integer> countSymbols(String sentence) {
return sentence.chars()
.filter(Character::isAlphabetic)
.mapToObj(c -> (char) c)
.collect(Collectors.toMap(Function.identity(),
counter -> 1,
Integer::sum,
LinkedHashMap::new));
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.