使用谓词验证搜索参数

时间:2017-03-20 07:48:25

标签: java lambda functional-programming java-8 predicate

我有一个validate()方法,用于检查在rest url中传递的参数。 参数链接到模型类,如下所示

class SearchCriteria {

String regno;
String hostid;
String domid;
String location;
String provider;

/*Getters and Setters*/
}

我有一个实用程序类,用于检查参数是否已设置。

public class SearchCriteriaUtil {

    public static boolean isRegnoSet(SearchCriteria criteria) {
        return null != criteria.getRegno();
    }

    public static boolean isHostIdSet(SearchCriteria criteria) {
        return null != criteria.getHostId();
    }

    /* Similarly for domid, location, provider */
}

我有一个谓词,它根据util中提供的条件进行测试并生成一个真值字符串

public class ParameterPredicate<T> implements Predicate<T>{

    final Predicate<T> predicate;
    final String sequence;

    public ParameterPredicate(Predicate<T> predicate, String sequence) {
        this.predicate = predicate;
        this.sequence = sequence;
    }

    @Override
    public String toString() {
        return sequence;
    }

    @Override
    public boolean test(T t) {
        return predicate.test(t);
    }
}

现在,根据参数set / notset, regno -set,hostid -set,domid - notset,location - notset,provider - set

我的谓词应根据SearchCriteriaUtil中的条件进行评估,并将序列设置为适当的真值......在这种情况下&#34; T T F F T&#34;

在我的验证方法中,

public void validateCriteria(SearchCriteria criteria) {
            List<Predicate<SearchCriteria>> SearchCriteriaPredicate = Arrays.asList(SearchCriteriaUtil::isRegnoSet, SearchCriteriaUtil::isHostIdSet,
                    SearchCriteriaUtil::isDomidSet,
                    SearchCriteriaUtil::isLocationSet,
                    SearchCriteriaUtil::isProviderSet,

Collection<String> desired = Arrays.asList("T F F F F", "T F T T F", "T F T T F", "T F F F T", "T F F F T", "F T F F F");

我无法超越这一点,我必须设置序列并检查它是否存在于所需的真值列表中。

我在推荐上一篇文章:Filtering with truth tables

由于我是java 8的新手,所以感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

为了检查条件的组合是否有效,不是使用util类和处理字符串,为什么不在SearchCriteria类中添加如下内容:

public boolean hasDesiredCombination() {
    return Criterion.DESIRED_COMBINATONS.contains(
            Arrays.stream(Criterion.values())
            .filter(s -> s.predicate.test(this))
            .collect(Collectors.toCollection(
                    () -> EnumSet.noneOf(Criterion.class)))
            );
}

private static enum Criterion {
    REGNO(s -> s.regno != null),
    HOSTID(s -> s.hostid != null),
    DOMID(s -> s.domid != null),
    LOCATION(s -> s.location != null),
    PROVIDER(s -> s.provider != null);

    private static Set<Set<Criterion>> DESIRED_COMBINATONS =
            new HashSet<>(Arrays.asList(
                    EnumSet.of(REGNO),
                    EnumSet.of(REGNO, DOMID, LOCATION),
                    EnumSet.of(REGNO, PROVIDER),
                    EnumSet.of(HOSTID)
                    ));

    private Predicate<SearchCriteria> predicate;

    private Criterion(Predicate<SearchCriteria> predicate) {
        this.predicate = predicate;
    }
}

优点:

  • 你不一定要公开吸气剂和制定者
  • 从源代码中立即明确了哪些组合
  • 逻辑是它所属的地方:(间接地)在SearchCriteria

答案 1 :(得分:1)

我不确定ParameterPredicate的用途是什么,但如果我理解正确,您需要检查验证组合(SearchCriteriaPredicate)是否与预定义集合(desired)匹配{1}})。如果是这样,应该这样做:

String sequence = SearchCriteriaPredicate.stream()
        .map(p -> p.test(criteria) ? "T" : "F")
        .collect(Collectors.joining(" "));

return desired.contains(sequence);