以简洁的方式记录 java8 谓词中的条件结果



我有这样的代码:

Predicate<String> notNull = input -> (input != null);
Predicate<String> notEmpty = input -> (input.trim().length() > 0);

我的验证器方法使用它,如下所示:

public boolean isInputValid(String input){
return (notNull.and(notEmpty)).test(input);
}

每当我调用isInputValid(<myInputString>)方法时,它都会返回 true 或 false,但是,如果我想记录哪个条件完全失败,我如何在 Java8 中做到这一点而不将我的谓词 notNull 和 notEmpty 转换为方法。

下面的示例将谓词 notNull 转换为方法将实现我记录输入问题的目标,但它太冗长了。有没有更好/更简洁的方法?

private Predicate<String> notNull(){
return input -> {
if(input == null){
log.warn("NULL input");
return false;
}
return true;
};
}

一种方法是创建一个高阶函数,该函数将一些日志记录代码包装在现有谓词周围,并返回可用于代替原始谓词的谓词。下面是此类函数的示例:

static <T> Predicate<T> loggingPredicate(String label, Predicate<? super T> pred) {
return t -> {
boolean r = pred.test(t);
System.out.printf("%s: %s => %s%n", label, t, r);
return r;
};
}

这将打印出每个调用的输入和结果。它还需要一个标签,以便您可以从日志中分辨出正在评估哪个谓词。您可以调整此设置,以便仅在谓词返回 false 或类似内容时打印日志消息。当然,您可以调整它以使用您喜欢的任何日志记录框架,而不是打印到 stdout。

然后,您可以获取现有谓词并将它们包装在对此函数的调用中:

Predicate<String> notNull = loggingPredicate("notNull", input -> (input != null));
Predicate<String> notEmpty = loggingPredicate("notEmpty", input -> (input.trim().length() > 0));

然后像以前一样使用notNullnotEmpty。每次评估其中一个时,您都会收到一条日志消息。

没有内置的解决方案,但您可以创建自定义可记录谓词来完成这项工作。

@FunctionalInterface
interface LPredicate<T> extends Predicate<T>{
default boolean testAndLog(T t, String prefix){
boolean result = this.test(t);
if(!result){
log.warn(prefix + " " + t);
}
return result;
}
}

完整的可测试代码

import java.util.function.Predicate;
public class FunctionLog {
static MLog log = new MLog();
@FunctionalInterface
interface LPredicate<T> extends Predicate<T>{
default boolean testAndLog(T t, String prefix){
boolean result = this.test(t);
if(!result){
log.warn(prefix + " " + t);
}
return result;
}
}
static LPredicate<String> notNull = input -> (input != null);
static LPredicate<String> notEmpty = input -> (input.trim().length() > 0);  
public static void main(String[] args) {        
System.out.println("Case1: " + isInputValid(""));
System.out.println("Case2: " + isInputValid(null));
System.out.println("Case3: " + isInputValid("hello"));
}
public static boolean isInputValid(String input){       
return notNull.testAndLog(input, "NULL Check Failed") && notEmpty.testAndLog(input, "EMPTY Check Failed");
}
}
/**
* Just a mock log class
*
*/
class MLog {
void warn(String str) {
System.out.println(str);
}
}

最新更新