Home > Enterprise >  Wildcard generic type of predicate in stream not applicable
Wildcard generic type of predicate in stream not applicable

Time:11-02

I have a trimmed down version of my code to illustrate the issue The method anyMatch(Predicate<? super capture#26-of ?>) in the type Stream<capture#26-of ?> is not applicable for the arguments (Predicate<Map<?,?>>) that I got:

private void func(Object o) {
    Predicate<Map<?, ?>> pred = m -> true;
    if (o instanceof Map && pred.test((Map<?, ?>) o)) {
        // ...pred.test is OK
    } else if (o instanceof Collection && ((Collection<?>) o).stream().filter(i -> i instanceof Map).anyMatch(pred)) {
        // ...anyMatch here gives the above error
    }
}

How would you fix the code to remove the error? Thank you!

CodePudding user response:

The fact that you have applied instanceof check in the filter() doesn't change the type of the stream, it remains to be Stream<Object>.

filter() operation is meant for discarding elements from the stream, not for modifying the elements, therefore it's not capable of changing the type of the stream.

To perform modifications, you need to apply map() operation and either use conversion via type cast or method Class.cast():

.<Map<?,?>>map(Map.class::cast)

or

.map(i -> (Map<?, ?>) i)

Alternatively, you can leverage Java 16 Pattern matching for instanceof combining both filter and map in one step by making use of mapMulty() which was also introduced with Java 16:

((Collection<?>) o).stream()
    .<Map<?,?>>mapMulti((i, consumer) -> {
        if (i instanceof Map m) consumer.accept(m);
    })
    .anyMatch(pred)

CodePudding user response:

After you filter just the Map you need to cast it to Map<?, ?>.

private void func(Object o) {
    Predicate<Map<?, ?>> pred = m -> true;
    if (o instanceof Map && pred.test((Map<?, ?>) o)) {
        // ...pred.test is OK
    } else if (o instanceof Collection && ((Collection<?>) o).stream()
        .filter(i -> i instanceof Map).map(i -> (Map<?, ?>)i).anyMatch(pred)) {
        // ...anyMatch here gives the above error
    }
}
  • Related