I wrote this generic predicate:
private static <T> Predicate<T> isNull(){
return Objects::isNull;
}
But I can't use it in combination with other predicates like this:
private static Predicate<String> isEmpty(){
return string -> string.isEmpty();
}
Because this snippet will not compile (expects Predicate< String> in or operation):
isNull().or(isEmpty())
Any idea to solve it? Thanks!
Since isNull()
is generic, and the compiler cannot infer the generic parameter when combined like that, you need to explicitly specify the type parameter.
To do that, you must qualify with the class name, e.g. Test
:
Test.<String>isNull().or(isEmpty())
Full example:
public class Test {
public static void main(String[] args) {
Predicate<String> isNullOrEmpty = Test.<String>isNull().or(isEmpty());
System.out.println(isNullOrEmpty.test(null)); // true
System.out.println(isNullOrEmpty.test("")); // true
System.out.println(isNullOrEmpty.test("Foo")); // false
}
private static <T> Predicate<T> isNull(){
return Objects::isNull;
}
private static Predicate<String> isEmpty(){
return string -> string.isEmpty();
}
}
You can also resolved it by assigning each part to a variable:
Predicate<String> isNull = isNull(); // String is inferred from assignment operator
Predicate<String> isEmpty = isEmpty();
Predicate<String> isNullOrEmpty = isNull.or(isEmpty);
Or just the first part:
Predicate<String> isNull = isNull();
Predicate<String> isNullOrEmpty = isNull.or(isEmpty());
Well in our project we have a small work-around for this:
private static <T> Predicate<T> allOr(Predicate<T> ... predicates) {
return Arrays.stream(predicates).reduce(Predicate::or).orElse(x -> true);
}
And using it with:
Predicate<String> both = allOr(isEmpty(), isNull());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With