在 Java Lambda 流过滤器中外部化谓词
Externalizing the Predicate in Java Lambda Stream Filter
我有一个数据模型的 ArrayList,它有 10 个基于用户输入的字段我需要将用户 selected 字段上的谓词条件动态应用到流过滤器。
下面的代码段应用了字段 itemDesc 之一,但在运行时用户可以select 任何字段。
Predicate<DataModel> contains = (n) -> n.getItemDesc().contains(query);
List filtered = data.stream().filter(contains).collect(Collectors.toList());
基本上我们需要动态构建谓词而不是预定义谓词,如果有的话是否可能有任何例子。提前致谢。
这取决于解决方案的动态程度。对于十个属性,在编译时有一个显式的属性列表而不是动态(反射)发现可能是可以接受的。
可用属性的声明可能类似于
enum DataModelProperty {
ITEM_DESC(DataModel::getItemDesc),
FOO(DataModel::getFoo),
BAR(DataModel::getBar)
// the other seven properties…
;
final Function<DataModel,String> getter;
private DataModelProperty(Function<DataModel, String> f) {
getter = f;
}
public Function<DataModel, String> getPropertyGetter() {
return getter;
}
public Predicate<DataModel> asPredicate(String query) {
return n -> getter.apply(n).contains(query);
}
}
然后您可以使用 DataModelProperty.values()
向用户呈现一个选择列表,还可以通过 Enum.name()
转换为持久的 String
表示,并通过 DataModelProperty.valueOf(String)
是可以的。
一旦您选择了 属性,使用它进行过滤就很容易了
DataModelProperty p=DataModelProperty.valueOf("ITEM_DESC");// just as example
List<DataModel> filtered = data.stream()
.filter(p.asPredicate(query))
.collect(Collectors.toList());
我有一个数据模型的 ArrayList,它有 10 个基于用户输入的字段我需要将用户 selected 字段上的谓词条件动态应用到流过滤器。
下面的代码段应用了字段 itemDesc 之一,但在运行时用户可以select 任何字段。
Predicate<DataModel> contains = (n) -> n.getItemDesc().contains(query);
List filtered = data.stream().filter(contains).collect(Collectors.toList());
基本上我们需要动态构建谓词而不是预定义谓词,如果有的话是否可能有任何例子。提前致谢。
这取决于解决方案的动态程度。对于十个属性,在编译时有一个显式的属性列表而不是动态(反射)发现可能是可以接受的。
可用属性的声明可能类似于
enum DataModelProperty {
ITEM_DESC(DataModel::getItemDesc),
FOO(DataModel::getFoo),
BAR(DataModel::getBar)
// the other seven properties…
;
final Function<DataModel,String> getter;
private DataModelProperty(Function<DataModel, String> f) {
getter = f;
}
public Function<DataModel, String> getPropertyGetter() {
return getter;
}
public Predicate<DataModel> asPredicate(String query) {
return n -> getter.apply(n).contains(query);
}
}
然后您可以使用 DataModelProperty.values()
向用户呈现一个选择列表,还可以通过 Enum.name()
转换为持久的 String
表示,并通过 DataModelProperty.valueOf(String)
是可以的。
一旦您选择了 属性,使用它进行过滤就很容易了
DataModelProperty p=DataModelProperty.valueOf("ITEM_DESC");// just as example
List<DataModel> filtered = data.stream()
.filter(p.asPredicate(query))
.collect(Collectors.toList());