问题
Consider the following code:
List<Locale> locales = Arrays.asList(
new Locale("en", "US"),
new Locale("ar"),
new Locale("en", "GB")
);
locales.stream().filter(l -> l.getLanguage() == "en");
How do I get the size of the locales ArrayList after applying filter, given that locales.size() gives me the size before applying filter?
回答1:
When you get a stream from the list, it doesn't modify the list. If you want to get the size of the stream after the filtering, you call count() on it.
long sizeAfterFilter =
locales.stream().filter(l -> l.getLanguage().equals("en")).count();
If you want to get a new list, just call .collect(toList()) on the resulting stream. If you are not worried about modifying the list in place, you can simply use removeIf on the List.
locales.removeIf(l -> !l.getLanguage().equals("en"));
Note that Arrays.asList returns a fixed-size list so it'll throw an exception but you can wrap it in an ArrayList, or simply collect the content of the filtered stream in a List (resp. ArrayList) using Collectors.toList()(resp. Collectors.toCollection(ArrayList::new)).
回答2:
Use the count() method:
long matches = locales.stream()
.filter(l -> l.getLanguage() == "en")
.count();
Note that you are comparing Strings using ==. Prefer using .equals(). While == will work when comparing interned Strings, it fails otherwise.
FYI it can be coded using only method references:
long matches = locales.stream()
.map(Locale::getLanguage)
.filter("en"::equals)
.count();
来源:https://stackoverflow.com/questions/29048988/how-to-get-the-size-of-a-stream-after-applying-a-filter-by-lambda-expression