用于筛选给定集合元素的java增量条件
我想知道一种可伸缩的通用方法,可以将增量filters
应用于给定的集合,而不会丢失失败的原因,我的意思是,哪个过滤器不匹配
以下代码是对现有代码的简化(它有更多的条件和错误消息):
public class FailureCause {
public static void main(String[] args) {
validateAtRawWay(asList(201, 300, 450));
validateAtRawWay(asList(20, 30, 40));
validateAtRawWay(asList(400, 1600));
validateAtRawWay(asList(10, 25, 36, 201, 1600));
}
public static void validateAtRawWay(List<Integer> sourceToCheck) {
System.out.println("Initial elements: " + sourceToCheck);
if (!sourceToCheck.stream()
.filter(FailureCause.upTo100())
.findAny()
.isPresent()) {
System.out.println("ERROR: no numbers less or equals than 100 were found");
return;
}
if (!sourceToCheck.stream()
.filter(FailureCause.isPerfectSquare())
.findAny()
.isPresent()) {
System.out.println("ERROR: no perfect square numbers were found");
return;
}
List<Integer> validResults = sourceToCheck.stream()
.filter(FailureCause.upTo100())
.filter(FailureCause.isPerfectSquare())
.collect(toList());
System.out.println("Valid data: " + validResults);
}
public static Predicate<Integer> upTo100() {
return i -> i <= 100;
}
public static Predicate<Integer> isPerfectSquare() {
return i -> {
double sq = Math.sqrt(i);
return (sq - Math.floor(sq)) == 0;
};
}
}
然而,使用这种方法,集合必须迭代数次,以了解错误,并最终获得验证所有条件的合适元素
作为上述方法的替代方法我开发了以下类来存储:过滤器、其重要性顺序、错误消息以及是否有验证它的元素
public class ConditionToMatch<E> implements Comparable<ConditionToMatch> {
// To omit getter/setter
public int order;
public Predicate<E> condition;
public boolean wasFound;
public String errorMessage;
public ConditionToMatch (int order, Predicate<E> condition, boolean wasFound, String errorMessage) {
this.order = order;
this.condition = condition;
this.wasFound = wasFound;
this.errorMessage = errorMessage;
}
@Override
public int compareTo(ConditionToMatch o) {
return ofNullable(o)
.map(ext -> Integer.compare(order, ext.order))
.orElse(-1);
}
}
将此用例添加到上一个FailureCause
类:
public class FailureCause {
public static void main(String[] args) {
...
validateWithConditionClass(asList(201, 300, 450));
validateWithConditionClass(asList(20, 30, 40));
validateWithConditionClass(asList(400, 1600));
validateWithConditionClass(asList(10, 25, 36, 201, 1600));
}
...
public static void validateWithConditionClass(List<Integer> sourceToCheck) {
System.out.println("Initial elements: " + sourceToCheck);
ConditionToMatch<Integer> isUpTo100Condition = isUpTo100ConditionToMatch();
ConditionToMatch<Integer> isPerfectSquareCondition = isPerfectSquareConditionToMatch();
// Used to get the "most important" filter has failed
PriorityQueue<ConditionToMatch> priorizeValidations = new PriorityQueue<>(asList(isUpTo100Condition, isPerfectSquareCondition));
List<Integer> validResults = sourceToCheck.stream()
.map(s -> {
if (isUpTo100Condition.condition.test(s)) {
isUpTo100Condition.wasFound = true;
}
if (isPerfectSquareCondition.condition.test(s)) {
isPerfectSquareCondition.wasFound = true;
}
return s;
})
.filter(isUpTo100Condition.condition)
.filter(isPerfectSquareCondition.condition)
.collect(toList());
if (validResults.isEmpty()) {
Iterator<ConditionToMatch> value = priorizeValidations.iterator();
// To know the first "most important" filter that failed
while (value.hasNext()) {
ConditionToMatch current = value.next();
if (!current.wasFound) {
System.out.println(current.errorMessage);
break;
}
}
}
else {
System.out.println("Valid data: " + validResults);
}
}
...
public static ConditionToMatch<Integer> isUpTo100ConditionToMatch() {
return new ConditionToMatch<>(1, FailureCause.upTo100(), false, "ERROR: no numbers less or equals than 100 were found");
}
public static ConditionToMatch<Integer> isPerfectSquareConditionToMatch() {
return new ConditionToMatch<>(2, FailureCause.isPerfectSquare(), false, "ERROR: no perfect square numbers were found");
}
}
我的问题是:有没有更好的、可扩展的方法
# 1 楼答案
我会调整你的第一种方法,避免那里的溪流
我不知道你要检查多少情况。即使你必须经常重复这个例子,我认为它更清晰。您还可以提取一个接受列表和谓词的方法,以减少重复的块
# 2 楼答案
通过直接在ConditionToMatch类中设置布尔值,可以更轻松地执行此操作:
然后,您可以编写一个通用检查器:
以及两个检查程序的具体实现:
当然还有创造条件的功能: