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?

+3


source to share


1 answer


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));

      

+3


source







All Articles