Java 8 - how to abstract the use of predicates with methods
I'm trying to create a class that abstracts the use of predicates from its end user.
My application uses Guava-Retrying extension which works great.
Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
.retryIfResult(Predicates.<Boolean>isNull())
....
.build();
retryer.call(callable);
I can call it easily using predicates and it will poll until the predicate returns false.
Now, maybe I misunderstood the predicates, but I am trying to create a class that will abstract them.
I would like to call it like this
MyPoller.poll(new PollCondition<MyClass>() {
@Override public boolean condition() {
return !isValid(result**.getPermissions(), permissionName);
}
});
So, I wrote the PollCondition class as follows.
public abstract class PollCondition<T> {
public Predicate<T> getCondition() {
return result -> condition();
}
public abstract boolean condition();
}
but the call to MyPoller.poll () is not compiled - the result is not declared.
Any idea?
source to share
You don't seem to understand predicates. A predicate is a function that takes an input as an argument and returns a boolean value (usually based on the input, of course).
Let's take a look at your PollCondition class:
public abstract class PollCondition<T> {
public Predicate<T> getCondition() {
return result -> condition();
}
public abstract boolean condition();
}
Thus, it defines an abstract condition()
method that takes nothing as an argument and returns a boolean value. And it can be "converted" into a predicate with getCondition()
. This method returns a predicate that takes an input as an argument (result), ignores it entirely, and always returns a boolean return value condition()
.
Then you create PollCondition using
new PollCondition<MyClass>() {
@Override public boolean condition() {
return !isValid(result.getPermissions(), permissionName);
}
}
It would be correct if there was a variable named in the scope where you were executing this code result
. But no. result
is actually a contribution to your fortune. Therefore, the class must be defined like this:
public abstract class PollCondition<T> {
public Predicate<T> getCondition() {
return result -> condition(result);
}
public abstract boolean condition(T result);
}
And then you should be able to instantiate using
new PollCondition<MyClass>() {
@Override public boolean condition(MyClass result) {
return !isValid(result.getPermissions(), permissionName);
}
}
But I really, really don't understand what this results in using plain Predicate directly.
Define MyPoller.poll () like this:
public poll(Predicate<T> predicate);
and use it like this:
MyPoller.poll(result -> !isValid(result.getPermissions(), permissionName));
source to share