I have a ArrayList of data-model which has 10 fields based on the user input I need to dynamically apply the Predicate condition on user selected field to Stream filter.
Below snippet applied with one of the field itemDesc, but at the runtime user can select any field.
Predicate<DataModel> contains = (n) -> n.getItemDesc().contains(query);
List filtered = data.stream().filter(contains).collect(Collectors.toList());
Basically we need to build the predicate dynamically instead of predefined, is it possible if so any examples. Thanks in advance.
It depends on how dynamic the solution has to be. For ten properties, it might be acceptable to have an explicit list of properties at compile time rather than a dynamic (reflective) discovery.
A declaration of the available properties might look like
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);
}
}
Then you can use DataModelProperty.values() to present the user a list of choices, but also a conversion to a persistent String representation via Enum.name() and reconstitution of the runtime object via DataModelProperty.valueOf(String) is possible.
Once you have the chosen property, using it for filtering is easy
DataModelProperty p=DataModelProperty.valueOf("ITEM_DESC");// just as example
List<DataModel> filtered = data.stream()
.filter(p.asPredicate(query))
.collect(Collectors.toList());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With