有没有办法在Java中模拟属性选择器



在C#中,我们可以选择使用属性选择器(例如使用LINQ时(类似的选项:

so:
var usernames = customers.Where(x => x.Age > 20).Select(x => x.Username);

在这里,我们首先选择属性Age以执行比较,然后将属性Username指定到Select(...)子句。

我当前正在尝试使用Java中的Lambda表达式复制此功能,以使我的代码的用户可以在以后的某些操作中指定哪些属性应使用。最终结果看起来应与以下内容相似:

public class Builder<T> {
// ...
private Field field;
Builder<T> forField(SomeFunctionalInterface s) {
    this.field = s.evaluate();
    return this;
 }
// ...
}

谢谢您的努力。

下面的示例将无错误地编译:

public void test() {
  from(Customer.class).where(c -> c.getAge() > 20).select(Customer::getUserName);
}
public <T> Builder<T> from(Class<T> cls) {
  return new Builder<>(cls);
}
public class Builder<T> {
  private Class<T> cls;
  public Builder(Class<T> cls) {
    this.cls = cls;
  }
  public Builder<T> where(Predicate<T> predicate) {
    // store predicate
    return this;
  }
  public Builder<T> select(Function<T, Object> field) {
    // store field selector
    return this;
  }
}
public class Customer {
  private String userName;
  private int age;
  public int getAge() {
    return age;
  }
  public String getUserName() {
    return userName;
  }
}

您无法直接访问private字段,您需要为它们访问一个。

您可以使用流API:

customers.stream().filter(customer => customer.getAge() > 20).map(Customer::getUserName).collect(Collectors.toList())

我是linq的作者到对象(Java(。您可以使用Lombok和Linq来含义。

val result = Linq.asEnumerable(customers).where(customer -> customer.getAge() > 20).select(customer -> customer.getUserName());

Lombok

linq

最新更新