For example, i have class
public class Human {
private String name;
...
}
and i want to implement something like this:
(1)
List<Human> humans = initHumans();
Equals<Human> humanEquals = new Equals<>();
Predicate<Human> filter = humanEquals.filter("name", "John");
List<Human> filteredHumans = humans
.stream()
.filter(filter)
.collect(Collectors.toList());
Equals:
public class Equals<T> extends AbstractPredicate<T> {
public java.util.function.Predicate<T> filter(String fieldName, String fieldValue) {
....
}
}
is it posible implement filter method to provide the (1) behavior?
I want to return a Predicate
like this:
Predicate<Human> predicate = human -> human.getName().equals("John");
similarly should work for other classes:
Predicate<Car> filter = humanEquals.filter("color", "red");
//like this:
Predicate<Car> predicate= human -> human.getColor().equals("red");
Yes, this might be achieved by reflection:
public static <T> Predicate<T> filter(Class<T> clazz, String fieldName, Object fieldValue) {
// 1
return (T instance) -> {
try {
final Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
return fieldValue.equals(field.get(instance));
} catch (NoSuchFieldException | IllegalAccessException e) {
// 2
}
return false;
};
}
static
because I have no idea what the AbstractPredicate
is and why you need to create an instance of a utility class.The use is:
final Predicate<Human> filter = Equals.filter(Human.class, "name", "John");
System.out.println(filter.test(new Human("John"))); // true
System.out.println(filter.test(new Human("Andrew"))); // false
There are still a few questions we need to think of - validating parameters (1), handling exceptions (2).
Another option can be using a Function<T, E>
to provide a reference to a getter:
public static <T, E> Predicate<T> filter(Function<T, E> supplier, E value) {
return (T instance) -> supplier.apply(instance).equals(value);
}
An example of use:
final Predicate<Human> predicate = Equals.filter(Human::getName, "John");
System.out.println(predicate.test(new Human("John"))); // true
System.out.println(predicate.test(new Human("Andrew"))); // false