Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a generic predicate in Java 8

I'm fairly new to Java 8 and wanted to know if its possible to pass instance methods to another method which in turn calls it on a lambda parameter:

Consider this class:

import java.util.function.Predicate;

public class PredicateTest {

    private class SomeType {

        public boolean bar() {
            return true;
        }

        public boolean foo() {
            return true;
        }
    }

    public void someMethod() {
        Predicate<SomeType> firstPredicate = someType -> someType.bar();
        Predicate<SomeType> secondPredicate = someType -> someType.foo();
        //...
    }

    public Predicate<SomeType> getGenericPredicate(/* ?? what goes here ?? */) {
        Predicate<SomeType> predicate = someType -> someType./* ?? how to call passed instance method foo or bar? */
        return predicate;
    }
}

In someMethod() two predicates of SomeType are created.

If SomeType would have 20 methods it might happen that we need to write 20 similar predicates.

I'm wondering if it is possible with Java 8 to avoid code duplication with a method like getGenericPredicate which could take bar() or foo() as parameter and returns the correct predicate.

The goal would be to refactor someMethod to something like this:

public void someMethodRefactored() {
        Predicate<SomeType> firstPredicate = getGenericPredicate(SomeType::bar());
        Predicate<SomeType> secondPredicate = getGenericPredicate(SomeType::foo());
        //...
}
like image 617
Juergen Avatar asked Jul 20 '14 13:07

Juergen


1 Answers

I am not sure why do you need getGenericPredicate since instead of

public void someMethodRefactored() {
    Predicate<SomeType> firstPredicate = getGenericPredicate(SomeType::bar());
    Predicate<SomeType> secondPredicate = getGenericPredicate(SomeType::foo());
    //...
}

you could simply use

public void someMethodRefactored() {
    Predicate<SomeType> firstPredicate = SomeType::bar;
    Predicate<SomeType> secondPredicate = SomeType::foo;
    //...
}

Assuming that getGenericPredicate would actually need to do some additional tasks (logging for instance) you could try with

public <T> Predicate<T> getGenericPredicate(Predicate<T> p) {
    //some additional code goes here
    return p;
}

and then you can use it like

public void someMethodRefactored() {
    Predicate<SomeType> firstPredicate = getGenericPredicate(SomeType::bar);
    Predicate<SomeType> secondPredicate = getGenericPredicate(SomeType::foo);
    //...
}
like image 165
Pshemo Avatar answered Oct 21 '22 12:10

Pshemo