How do I write below code in Java 8 using Stream API?

Is there any way to write the following code using Streams?

public Map<String, Integer> process() {
    List<String> words = Arrays.asList(message.toLowerCase().split("[?.\\s]+"));
    Map<String, Integer> countMap = new HashMap<>();

    for (String word : words) {
        if (word.length() > 2) {
            Integer count = countMap.getOrDefault(word, 0);
            countMap.put(word, count + 1);
        }
    }
    return countMap;
}

2 answers

  • answered 2018-04-17 06:12 Eran

    You can use Collectors.toMap to generate the Map:

    Map<String, Integer> countMap =
        words.stream()
             .filter(word -> word.length() > 2)
             .collect(Collectors.toMap(Function.identity(),w -> 1, Integer::sum));
    

    Of course you can skip Arrays.asList and create a Stream directly from the array:

    Map<String, Integer> countMap =
        Arrays.stream (message.toLowerCase().split("[?.\\s]+"))
              .filter(word -> word.length() > 2)
              .collect(Collectors.toMap(Function.identity(),w -> 1, Integer::sum));
    

  • answered 2018-04-17 06:16 mtj

    Start out with

    Pattern.compile("[?.\\s]+").splitAsStream(message.toLowerCase())
    

    if you can live with a long result, stick with Ravindra's solution, if you need int, use Eran's counter.

    So either:

    Map<String, Long> r = Pattern.compile("[?.\\s]+").splitAsStream(message.toLowerCase())
        .filter(w -> w.length() > 2)
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
    

    or

    Map<String, Integer> r = Pattern.compile("[?.\\s]+").splitAsStream(message.toLowerCase())
        .filter(w -> w.length() > 2)
        .collect(Collectors.toMap(Function.identity(), w -> 1, Integer::sum));
    

    or (after the comment below) (even better)

    Map<String, Integer> r = Pattern.compile("[?.\\s]+").splitAsStream(message.toLowerCase())
        .filter(w -> w.length() > 2)
        .collect(Collectors.groupingBy(Function.identity(), Collectors.summingInt(x -> 1)));