Reputation: 2662
I have a Map<String, ? extends Collection<SomeClass>>
. I would like to ensure that there are no entries where collection's size is 0. Therefore I tried myMap.values().stream().map(Collection::size).allMatch(size -> size > 0)
. However, as it turned out, myMap contains null entries.
I wanted to check if my map contains null entries: resourceMap.values().stream().noneMatch(null)
but I got an Exception java.util.Objects.requireNonNull
.
I decided to do it in a relatively old fashioned way, with a for-in
loop for (Map.Entry<String, ? extends Collection> entry : myMap)
However, I got a compilation error telling me that foreach is not applicable to my Map.
What is an elegant way to check if all entries in my map are not null and with size > 0?
Upvotes: 1
Views: 807
Reputation: 298143
You can just check for null
s using myMap.values().contains(null)
—no Stream API required.
If your map was consistently using List
or Set
, you could also check for empty values with myMap.values().contains(Collections.emptySet())
or myMap.values().contains(Collections.emptyList())
, but since there is no general equality contract between arbitrary collections, that doesn’t work for your Map<String, ? extends Collection<SomeClass>>
.
So for this specific test, you could use
boolean violations = myMap.values().contains(null)
|| myMap.values().stream().anyMatch(Collection::isEmpty);
or
boolean violations = myMap.values().stream().anyMatch(col -> col==null || col.isEmpty());
When you want to iterate with a for
loop, you have to specify a Collection view over the Map
, e.g.
Map<String, ? extends Collection<SomeClass>> myMap;
…
for (Map.Entry<String, ? extends Collection<?>> entry: myMap.entrySet())
// loop body
or, much better for this use case
for(Collection<?> value: myMap.values())
if(value == null || value.isEmpty())
// violation detected, perform your action
Upvotes: 6
Reputation: 13773
If you have a look at the actual method signature:
boolean noneMatch(Predicate<? super T> predicate)
You will see that noneMatch(null)
accepts a Predicate
instance and not an actual value. Null predicates are forbidden here.
Try:
boolean result = resourceMap.values().stream()
.noneMatch(Objects::isNull)
You can merge those two into one chain:
myMap.values().stream()
.allMatch(col -> col != null && col.size() > 0);
Upvotes: 3