【问题标题】:Using a predicate for a query on a field使用谓词查询字段
【发布时间】:2017-10-03 21:38:10
【问题描述】:

我在搞乱 lambda,我正在尝试创建一种通用方法来为字段上的类形成谓词。这里有一些代码来说明:

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());
}
}

如何编写 createPred 以便它可以占用一个字段?我想我希望该方法是“字段通用的”。我猜这里使用 java 反射不是一个好主意。

【问题讨论】:

  • 你不能把它作为参数传递给createPred 并在你的new Predicate 正文中使用吗?
  • 反射似乎是唯一可能的方法,是的,使用反射通常不是一个好主意(我看到通过反射实现的大多数“友好”想法最终在问题和维护方面比输入他们保存)。
  • 如果我猜对了,你可以在这里使用Function&lt;A, String&gt;。将其放入您的方法中,然后使用t -&gt; t.getB() 之类的名称调用该方法,例如createPred("...", t -&gt; t.getB());。这将允许您将 A 的任何 String 字段提供给测试方法。
  • @FlorianSchaetz 这似乎是最合理的方法。即使它不一定“字段泛化”它。
  • @FlorianSchaetz 有正确的想法。但是如果你可以使用 getter 而不是字段(如 Florian 的示例),你可以让它更漂亮一点:createPred(t::getB)

标签: java lambda functional-programming predicate higher-order-functions


【解决方案1】:

您可以让您的方法采用 Function 和 T 作为查询字段。

  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());
    }
  }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多