我有一个数据模型的ArrayList,根据用户输入有10个字段,我需要动态地将用户选择字段上的Predicate条件应用于Stream过滤器。
在下面的代码段中应用了一个字段itemDesc,但在运行时用户可以选择任何字段。
Predicate<DataModel> contains = (n) -> n.getItemDesc().contains(query);
List filtered = data.stream().filter(contains).collect(Collectors.toList());
基本上我们需要动态地而不是预定义地构建谓词,如果是这样的话,任何例子都是可能的。提前谢谢。
答案 0 :(得分:3)
这取决于解决方案的动态程度。对于十个属性,在编译时拥有明确的属性列表而不是动态(反射)发现可能是可以接受的。
可用属性的声明可能类似于
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()
向用户显示选项列表,还可以通过String
转换为持久Enum.name()
表示,并通过{{1}重构运行时对象可能。
获得所选属性后,使用它进行过滤很容易
DataModelProperty.valueOf(String)