menteith
menteith

Reputation: 678

Count the occurrence of each letter in a sentence using a stream

I'd like to count the occurrence of each letter in a sentence and store the result in Map<Character, Integer>. This could be easily done using a simple loop, but as an exercise I'd like to write it using a stream. I thought of using collect(toMap()) to produce a map whose values are the characters itself (so I used Function.identity()) and the number of occurrences. I've come up with the following (non-compiling) code:

"a simple sentence".chars()                
.collect(toMap(Collectors.partitioningBy(Function.identity(), 
Collectors.counting())));

Upvotes: 2

Views: 198

Answers (2)

Ousmane D.
Ousmane D.

Reputation: 56423

You're actually close, to finish off what you've started, you need to use the mapToObj intermediate operation and a groupingBy collector instead of partitioningBy as follows:

Map<Character, Long> result = "a simple sentence".chars()
                .mapToObj(c -> (char) c)
                .collect(groupingBy(Function.identity(),
                        counting()));

or if you want the map keys to be strings then you can do:

Map<String, Long> result = "a simple sentence".chars()
                .mapToObj(c -> String.valueOf((char) c))
                .collect(groupingBy(Function.identity(),
                        counting()));

or if you want the occurrence of all characters except the whitespace character:

Map<String, Long> result = "a simple sentence".chars()
                .filter(c -> !Character.isSpaceChar(c))
                .mapToObj(c -> String.valueOf((char) c))
                .collect(groupingBy(Function.identity(),
                        counting()));

or using a pattern:

Map<String, Long> result = 
     Pattern.compile("\\s+")
            .splitAsStream("a simple sentence")
            .flatMap(s -> Arrays.stream(s.split("")))
            .collect(groupingBy(Function.identity(),
                        counting()));

a more efficient version using pattern:

Map<String, Long> result = 
     Pattern.compile("") 
            .splitAsStream("a simple sentence")
            .filter(s -> !s.trim().isEmpty())
            .collect(Collectors.groupingBy(Function.identity(),Collectors.counting()));

Upvotes: 3

amrender singh
amrender singh

Reputation: 8239

Try the following:

String string ="a simple sentence";
Map<String, Long> map = 
 Arrays.stream(string.split("")).
 collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

Upvotes: 3

Related Questions