Как получить размер потока после применения фильтра лямбдой

List<Locale> locales = Arrays.asList(
    new Locale("en", "US"),
    new Locale("ar"),
    new Locale("en", "GB")
); 

locales.stream().filter(l -> l.getLanguage() == "en");

Теперь, как мне получить размер locales ArrayList после, применяя filter, учитывая, что locales.size() дает мне размер до, применяя filter?

Ответы

Ответ 1

Когда вы получаете поток из списка, он не изменяет список. Если вы хотите получить размер потока после фильтрации, вы вызываете count() на нем.

long sizeAfterFilter = 
    locales.stream().filter(l -> l.getLanguage().equals("en")).count();

Если вы хотите получить новый список, просто вызовите .collect(toList()) в результирующем потоке. Если вы не беспокоитесь об изменении списка на месте, вы можете просто использовать removeIf в List.

locales.removeIf(l -> !l.getLanguage().equals("en"));

Обратите внимание, что Arrays.asList возвращает список фиксированного размера, поэтому он генерирует исключение, но вы можете обернуть его в ArrayList или просто собрать содержимое отфильтрованного потока в List (соответственно ArrayList), используя Collectors.toList() (соответственно Collectors.toCollection(ArrayList::new)).

Ответ 2

Используйте метод count():

int matches  = locales.stream()
  .filter(l -> l.getLanguage() == "en")
  .count();

Обратите внимание, что вы сравниваете строки с помощью ==. Предпочитают использовать .equals(). Хотя == будет работать при сравнении интернированных строк, в противном случае это не сработает.


FYI он может быть закодирован с использованием только ссылок на методы:

int matches = locales.stream()
  .map(Locale::getLanguage)
  .filter("en"::equals)
  .count();