-1

how to count specific words in the list and return it as int

strings.stream().filter(element -> element.equals("")).count();

returns long.

If shortly, how to write this code by using stream?

private static int getCountEmptyStringLoop(List<String> strings) {
        int counter = 0;
        for (int i = 0; i < strings.size(); i++) {
            if (strings.get(i).equals("")){
                counter++;
            }
        }
        return counter;
    }

I began to learn streams and I don't really understand how it works.

ETO
  • 6,970
  • 1
  • 20
  • 37
  • The count() of interface Stream returns long, there is no standard implementation returning int. Hence you can just [convert long to int](https://stackoverflow.com/questions/4355303/how-can-i-convert-a-long-to-int-in-java) - of course being careful for the potential too-large size of the .count() result – Matteo NNZ Mar 30 '21 at 21:45
  • 2
    You better use `"".equals(element)` than `element.equals("")`. In the first case, the `null` string will be processed correctly. Second code will throw an exception if the `element == null`. – chptr-one Mar 30 '21 at 21:54
  • @chptr-one Yes, exactly. That's much safer. – ETO Mar 30 '21 at 21:55
  • 4
    Just use [`Collections.frequency(strings, "")`](https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/util/Collections.html#frequency(java.util.Collection,java.lang.Object)) which is the simplest approach, returns an `int`, and exists since JDK 1.5. – Holger Mar 31 '21 at 10:56

3 Answers3

2

Just manually cast the count to int:

private static int getCountEmptyStringLoop(List<String> strings) {
    return (int) strings.stream()
                        .filter(""::equals)
                        .count();
}

or

private static int getCountEmptyStringLoop(List<String> strings) {
    return (int) strings.stream()
                        .filter(Objects::nonNull)
                        .filter(String::isEmpty)
                        .count();
}
ETO
  • 6,970
  • 1
  • 20
  • 37
1

The problem is that you are using count(), which will return long.

Please, try instead:

int count = words.stream()
  .mapToInt(word -> "".equals(word) ? 1 : 0)
  .sum()
;

Or:

int count = words.stream()
  .map(word -> "".equals(word) ? 1 : 0)
  .reduce(0, (a, b) -> a + b)
;

Very similar:

int count = words.stream()
  .map(word -> "".equals(word) ? 1 : 0)
  .reduce(0, Integer::sum)
;

Or using collectors:

int count = words.stream()
  .map(word -> "".equals(word) ? 1 : 0)
  .collect(Collectors.summingInt(Integer::intValue))
;

Or, much better, in one row, as suggested by @Holger:

int count = words.stream()
  .collect(Collectors.summingInt(word -> "".equals(word) ? 1 : 0))
;

All these examples can be enclosed in a method, more general, like this:

import java.util.Objects;

//...

public int getCount(List<String> terms, String searchTerm) {
  Objects.requireNonNull(terms, "Null terms list provided");

  int count = terms.stream()
      .mapToInt(word -> Objects.equals(searchTerm, word)? 1 : 0)
      .sum();
  ;
  
  return count;
}

In your use case:

int countOfEmptyString = getCount(words, "");

As a side note, to avoid npe issues and null checking, always compare the information like this ("" will never be null):

"".equals(element)

Instead of (element can be null):

element.equals("")

By the way, the @ETO answer is a very suitable alternative as well.

jccampanero
  • 50,989
  • 3
  • 20
  • 49
0
public static <T> long countTokens(List<T> list, T token) {
     return list.stream().filter(item -> item.equals(token)).count();
}
Ryan
  • 1,762
  • 6
  • 11