Java 使用谓词验证搜索参数

Java 使用谓词验证搜索参数,java,lambda,functional-programming,java-8,predicate,Java,Lambda,Functional Programming,Java 8,Predicate,我有一个validate()方法,用于检查RESTURL中传递的参数。 这些参数链接到一个模型类,如下所示 class SearchCriteria { String regno; String hostid; String domid; String location; String provider; /*Getters and Setters*/ } 我有一个实用程序类,用于检查参数是否已设置 public class SearchCriteriaUtil { public

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

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);
    }
}
公共类ParameterPredicate实现谓词{
最后谓语;
最后的字符串序列;
公共参数解释(谓词,字符串序列){
this.predicate=谓词;
这个序列=序列;
}
@凌驾
公共字符串toString(){
返回序列;
}
@凌驾
公共布尔测试(T){
返回谓词test(t);
}
}
现在,根据参数set/notset, regno-set,hostid-set,domid-notset,location-notset,provider-set

我的谓词应该根据SearchCriteriaUtil中的条件进行计算,并将序列设置为适当的真值…在本例中为“T”

在我的验证方法中

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");
public void validateCriteria(搜索标准){
List SearchCriteriaPredicate=Arrays.asList(SearchCriteriaUtil::isRegnoSet,SearchCriteriaUtil::isHostIdSet,
SearchCriteriaUtil::isDomidSet,
SearchCriteriaUtil::isLocationSet,
SearchCriteriaUtil::isProviderSet,
所需集合=数组.asList(“tff F”、“tft T F”、“tft F”、“tf F T”、“tf F T”、“tf F T”、“F F F F T”);
我不能超过这一点,我必须设置序列并检查它是否存在于期望的真值列表中

我指的是以前的一篇帖子:


由于我是java 8新手,非常感谢您的帮助。

我不确定
ParameterPredicate
的目的是什么,但如果我理解正确,您希望检查验证组合(
SearchCriteriaPredicate
)是否与预定义集(
所需的
)中的一个匹配。如果是,应该这样做:

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

return desired.contains(sequence);

与其使用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;
    }
}
public boolean hasdiredCombination(){
返回条件。所需的组合包含(
Arrays.stream(criteria.values())
.filter(s->s.predicate.test(此))
.collect(收集器(
()->EnumSet.noneOf(criteria.class)))
);
}
私有静态枚举标准{
REGNO(s->s.REGNO!=null),
HOSTID(s->s.HOSTID!=null),
DOMID(s->s.DOMID!=null),
位置->位置!=null),
提供程序(s->s.PROVIDER!=null);
专用静态集所需的\u组合=
新哈希集(Arrays.asList)(
枚举集合(REGNO),
枚举集合(REGNO、DOMID、LOCATION),
枚举集(REGNO,PROVIDER),
枚举集(主机ID)
));
私有谓词;
私有条件(谓词){
this.predicate=谓词;
}
}
优点:

  • 您不必公开getter和setter
  • 从源代码中可以立即清楚地看出需要哪些组合
  • 逻辑是它所属的:(间接地)在
    SearchCriteria
    类中

在本例中为“T T F F T”-在哪种情况下?同样,在
所需的
中是否存在重复序列的原因?例如,当regno-set、hostid-set、domid-notset、location-notset、provider-set我的谓词应该设置值“T T F T”。这是一个错误,每个字符串都是唯一的。\u组合还可以定义为Stream.of(EnumSet.of(REGNO)、EnumSet.of(REGNO、DOMID、LOCATION)、EnumSet.of(REGNO、PROVIDER)、EnumSet.of(HOSTID))。collect(toSet())。谢谢你的建议。我相信还有进一步优化的可能性,例如,如果总是执行
null
-检查,则不要为条件存储
谓词
,而是存储值提取器。这取决于如何使用代码,以及是否希望尽可能多地使用Java 8功能.非常感谢您的解决方案!这对我很有效!