我有这样的代码:
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转换为方法。
下面的示例将Predicate notNull转换为方法将实现我记录输入问题的目标,但它太冗长了。有没有更好/更简洁的方法?
private Predicate<String> notNull(){
return input -> {
if(input == null){
log.warn("NULL input");
return false;
}
return true;
};
}
答案 0 :(得分:6)
一种方法是创建一个高阶函数,该函数将一些记录代码包装在现有谓词周围,并返回可以代替原始谓词使用的谓词。这是此类功能的示例:
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));
然后像以前一样使用notNull
和notEmpty
。每次对其中之一进行评估时,您都会收到一条日志消息。
答案 1 :(得分:4)
对此没有内置的解决方案,但是您可以创建自定义可记录谓词来完成这项工作。
@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);
}
}