I am trying to create a class that abstracts the use of predicates from its end user.
My app uses Guava-Retrying extension which works great.
Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
.retryIfResult(Predicates.<Boolean>isNull())
....
.build();
retryer.call(callable);
I can call easily call it with predicates and it polls until predicate returns false.
Now, maybe I misunderstand predicates but I am trying to create a class that will abstract them.
I wish to call it as follows
MyPoller.poll(new PollCondition<MyClass>() {
@Override public boolean condition() {
return !isValid(result**.getPermissions(), permissionName);
}
});
So I wrote PollCondition class as follows.
public abstract class PollCondition<T> {
public Predicate<T> getCondition() {
return result -> condition();
}
public abstract boolean condition();
}
but MyPoller.poll() call fail to compile - result is not declared.
Any idea?
It seems you don't understand predicates indeed. A predicate is a function that takes an input as argument, and returns a boolean value (usually based on the input, of course).
Let's examine your PollCondition
class:
public abstract class PollCondition<T> {
public Predicate<T> getCondition() {
return result -> condition();
}
public abstract boolean condition();
}
So it defines an abstract condition()
method that doesn't take anything as argument, and returns a boolean. And it can be "transformed" into a Predicate using getCondition()
. This method returns a predicate which takes an input as argument (result), ignores it completely, and always returns the boolean returned by condition()
.
You then create a PollCondition
using
new PollCondition<MyClass>() {
@Override public boolean condition() {
return !isValid(result.getPermissions(), permissionName);
}
}
That would be correct if, in the scope where you execute that code, there was a variable named result
. But there is not. result
is in fact an input to your condition. So the class should in fact defined like this:
public abstract class PollCondition<T> {
public Predicate<T> getCondition() {
return result -> condition(result);
}
public abstract boolean condition(T result);
}
And you would then be able to instantiate one using
new PollCondition<MyClass>() {
@Override
public boolean condition(MyClass result) {
return !isValid(result.getPermissions(), permissionName);
}
}
But I really, really don't see what that brings over using a simple Predicate directly.
Define MyPoller.poll()
like this:
public poll(Predicate<T> predicate);
and use it like this:
MyPoller.poll(result -> !isValid(result.getPermissions(), permissionName));