6

I often use the double-colon notation for brevity.

I am writing the following method that takes a short list of entities, validates them, and saves back to database.

@Override@Transactional
public void bulkValidate(Collection<Entity> transactions)
{
    Consumer<Entity> validator = entityValidator::validate;
    validator = validator.andThen(getDao()::update);
    if (transactions != null)
        transactions.forEach(validator);

}

I'd like to know if there is a shorthand syntax avoiding to instantiate the validator variable

Following syntax is invalid ("The target type of this expression must be a functional interface")

transactions.forEach((entityValidator::validate).andThen(getDao()::update));
usr-local-ΕΨΗΕΛΩΝ
  • 26,101
  • 30
  • 154
  • 305

1 Answers1

7

You could do that, but you would need to cast explicitly...

 transactions.forEach(((Consumer<Entity>)(entityValidator::validate))
                             .andThen(getDao()::update));

The thing is that a method reference like this entityValidator::validate does not have a type, it's a poly expression and it depends on the context.

You could also define a method to combine these Consumers:

@SafeVarargs
private static <T> Consumer<T> combine(Consumer<T>... consumers) {
    return Arrays.stream(consumers).reduce(s -> {}, Consumer::andThen);
}

And use it:

transactions.forEach(combine(entityValidator::validate, getDao()::update))
Eugene
  • 117,005
  • 15
  • 201
  • 306