/java/

Functional Interface Predicate. Repetition

2015-04-08 00:40:06

Imaging you have list of items:

List

<person> people = new ArrayList&lt;&gt;();
people.add(new Person("marta", "F", 30));
people.add(new Person("michal", "M", 29));
people.add(new Person("jakub", "M", 17));
people.add(new Person("alicja", "F", 28));

where Person object looks like this:

package pl.btbw.predicate;

public class Person {

    private String name;
    private String sex;
    private int age;

    public Person(String name, String sex, int age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public String getSex() {
        return sex;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age=" + age +
                '}';
    }
}

and you want to filter this list by "sex"

you can do something like this

for (Person person : people) {
    if(person.getSex().equals("M")){
        System.out.println(person);
    }
}

ugly as f*, don't do that

there is a better way, you have to create Interface

package pl.btbw.predicate;

public interface CheckPerson {

    boolean test(Person person);

}

and now, you can do something like this

package pl.btbw.predicate;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;

public class App {

    public static void main(String[] args) {

        List<person> people = new ArrayList<person>();
        people.add(new Person("marta", "F", 30));
        people.add(new Person("michal", "M", 29));
        people.add(new Person("jakub", "M", 17));
        people.add(new Person("alicja", "F", 28));

        printPersonWithCustomInterface(people, new CheckPerson() {
            public boolean test(Person person) {
                return person.getSex().equals("M");
            }
        });

    }

    private static void printPersonWithCustomInterface(List<person> people, CheckPerson checkPerson) {
        for (Person person : people) {
            if (checkPerson.test(person)) {
                System.out.println(person);
            }
        }
    }

}

What do you achieve with this approach ?

you can simply change the condition

printPersonWithCustomInterface(people, new CheckPerson() {
    public boolean test(Person person) {
        return person.getSex().equals("M");
    }
});

printPersonWithCustomInterface(people, new CheckPerson() {
    public boolean test(Person person) {
        return person.getSex().equals("F");
    }
});

printPersonWithCustomInterface(people, new CheckPerson() {
    public boolean test(Person person) {
        return person.getAge() &gt; 20;
    }
});

but please we have 2015, Java 8 is ready to use, remove then anonymous inner class and please use Lambda

package pl.btbw.predicate;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;

public class App {

    public static void main(String[] args) {

        List<person> people = new ArrayList&lt;&gt;();
        people.add(new Person("marta", "F", 30));
        people.add(new Person("michal", "M", 29));
        people.add(new Person("jakub", "M", 17));
        people.add(new Person("alicja", "F", 28));

        printPersonWithCustomInterface(people,
                p -&gt; p.getSex().equals("M")
        );

    }

    private static void printPersonWithCustomInterface(List<person> people, CheckPerson checkPerson) {
        for (Person person : people) {
            if (checkPerson.test(person)) {
                System.out.println(person);
            }
        }
    }

}

ok nice, but still we can improve something

we can remove our CheckPerson interface, and use delivered with JDK FunctionalInterface Predicate

package pl.btbw.predicate;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;

public class App {

    public static void main(String[] args) {

        List<person> people = new ArrayList&lt;&gt;();
        people.add(new Person("marta", "F", 30));
        people.add(new Person("michal", "M", 29));
        people.add(new Person("jakub", "M", 17));
        people.add(new Person("alicja", "F", 28));

        printPersonWithPredicate(people,
                p -&gt; p.getSex().equals("M")
        );

    }

    private static void printPersonWithPredicate(List<person> people, Predicate<person> predicate) {
        for (Person person : people) {
            if (predicate.test(person)) {
                System.out.println(person);
            }
        }
    }

}

now is OK but still, this is not the end of the story, yet we have stream, but about that maybe in the next post