Пока «лучший путь» очень расплывчатый.Вот одна интерпретация, которая, по крайней мере, является хорошей отправной точкой, объединяющей список правил для фильтрации полей в объектах, которые можно расширять, не ограничиваясь количеством полей или объектов, легко взаимозаменяемых типов и т. Д.
Сначала давайте определимнекоторые объекты данных для захвата модели данных:
static class Rule {
final int id;
final int valueToApply;
final Predicate<String>[] valueFilters;
public Rule(int id, int valueToApply, Predicate<String>... valueFilters) {
this.id = id;
this.valueToApply = valueToApply;
this.valueFilters = valueFilters;
}
@Override
public String toString() {
return "Rule{id="+id+", valueToApply="+valueToApply+"}";
}
}
static class X {
final String[] values;
X(String... values) {
this.values = values;
}
}
Затем основной метод, использующий их с предложенными в данных:
public static void main(String[] args) {
X x1 = new X("abc", "def", "ghi");
X x2 = new X("abc", "def", "hij");
List<Rule> rules = new ArrayList<>(Arrays.asList(
new Rule(1, 10, v->"abc".equals(v)),
new Rule(2, 25, v->"abc".equals(v), v->"def".equals(v)),
new Rule(3, 20, v->"abc".equals(v), v->true, v->"ghi".equals(v))
));
Collection<Rule> rulesResult = classify(x1, rules);
System.out.println("Case 1:"+rulesResult);
rulesResult = classify(x2, rules);
System.out.println("Case 2:"+rulesResult);
}
Ожидаемый результат:
Case 1:[Rule{id=1, valueToApply=10}, Rule{id=2, valueToApply=25}, Rule{id=3, valueToApply=20}]
Case 2:[Rule{id=1, valueToApply=10}, Rule{id=2, valueToApply=25}]
И «магия» метода классификации.
static Collection<Rule> classify(X x, Collection<Rule> rules) {
List<Rule> result = new ArrayList<>();
for (Rule rule : rules) {
for (int i = 0; i < x.values.length; i++) {
if (rule.valueFilters.length > i && !rule.valueFilters[i].test(x.values[i]))
continue;
if (i == x.values.length-1)
result.add(rule);
}
}
return result;
}
Ничего существенного, на что можно было бы обратить внимание.rule.valueFilters.length > i
есть, поэтому вам не нужно указывать конечные фильтры в правилах, которые все возвращают true.
Я уверен, что можно использовать потоки, но читабельность будет сомнительной и, скорее всего, неэффективной дляпакетная работа, подобная этой, в которой нет раннего завершения / ленивых преимуществ eval.
Цикл над объектами класса X.