I'm messing around with lambdas and I'm trying to create a generic way to form a predicate for a class on a field. Here's some code to illustrate:
public class A {
private String b;
private String c;
public A(String b, String c) {
this.b = b;
this.c = c;
}
public String getB() {
return b;
}
public String getC() {
return c;
}
}
public class Main {
public static void main(String[] args) {
List<A> list = Arrays.asList(new A("aa","bb"),new A("aaC","bb"));
Test test = new Test();
test.setList(list);
test.createPred("aa");
}
}
public class Test {
private List<A> list;
public void setList(List<A> list) {
this.list = list;
}
public Predicate<A> createPred(String query) {
return new Predicate<A>() {
@Override
public boolean test(A t) {
return t.getB().equals(query);
}
};
}
public List<A> search(Predicate<A> a) {
return list.stream().filter(a).collect(Collectors.toList());
}
}
How can I write createPred so it can take a field? I want the method to be "field-generic" I suppose. I'm guessing using java reflection here is not a good idea.
You can make your method take a Function and a T as the query field.
public static void main(String[] args) {
List<A> list = Arrays.asList(new A("aa", "bb"), new A("aaC", "bb"));
Test test = new Test();
test.setList(list);
test.createPred("aa", A::getB);
}
public static class Test {
private List<A> list;
public void setList(List<A> list) {
this.list = list;
}
public <T> Predicate<A> createPred(T query, Function<A, T> f) {
return new Predicate<A>() {
@Override
public boolean test(A x) {
return f.apply(x).equals(query);
}
};
}
public List<A> search(Predicate<A> a) {
return list.stream().filter(a).collect(Collectors.toList());
}
}