Java 使用谓词验证搜索参数
我有一个validate()方法,用于检查RESTURL中传递的参数。 这些参数链接到一个模型类,如下所示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
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
所需的
中是否存在重复序列的原因?例如,当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功能.非常感谢您的解决方案!这对我很有效!