以简洁的方式在 java8 谓词中记录条件结果
Logging the conditional outcome in java8 Predicate in a concise manner
我有这样的代码:
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>)
方法时,它会 return 我是真还是假,但是,如果我想记录哪个条件完全失败,我怎么能在 Java8 中做到这一点无需将我的 Predicates notNull 和 notEmpty 转换为方法。
下面将 Predicate notNull 转换为方法的示例将实现我记录输入问题的目标,但它太冗长了。有 better/more-concise 的方法吗?
private Predicate<String> notNull(){
return input -> {
if(input == null){
log.warn("NULL input");
return false;
}
return true;
};
}
对此没有内置解决方案,但您可以创建自定义可记录谓词来完成这项工作。
@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);
}
}
一种方法是创建一个高阶函数,将一些日志记录代码包装在现有谓词周围,returns 一个可以用来代替原始谓词的谓词。这是此类函数的示例:
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;
};
}
这会打印出每次调用的输入和结果。它还带有一个标签,以便您可以从日志中判断正在评估哪个谓词。您可以调整它,以便它仅在谓词 returns 为假或类似情况时打印一条日志消息。当然,您可以调整它以使用您喜欢的任何日志记录框架,而不是打印到标准输出。
然后,您可以使用现有谓词并将它们包装在对此函数的调用中:
Predicate<String> notNull = loggingPredicate("notNull", input -> (input != null));
Predicate<String> notEmpty = loggingPredicate("notEmpty", input -> (input.trim().length() > 0));
然后像以前一样使用notNull
和notEmpty
。每次评估其中一个时,您都会收到一条日志消息。
我有这样的代码:
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>)
方法时,它会 return 我是真还是假,但是,如果我想记录哪个条件完全失败,我怎么能在 Java8 中做到这一点无需将我的 Predicates notNull 和 notEmpty 转换为方法。
下面将 Predicate notNull 转换为方法的示例将实现我记录输入问题的目标,但它太冗长了。有 better/more-concise 的方法吗?
private Predicate<String> notNull(){
return input -> {
if(input == null){
log.warn("NULL input");
return false;
}
return true;
};
}
对此没有内置解决方案,但您可以创建自定义可记录谓词来完成这项工作。
@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);
}
}
一种方法是创建一个高阶函数,将一些日志记录代码包装在现有谓词周围,returns 一个可以用来代替原始谓词的谓词。这是此类函数的示例:
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;
};
}
这会打印出每次调用的输入和结果。它还带有一个标签,以便您可以从日志中判断正在评估哪个谓词。您可以调整它,以便它仅在谓词 returns 为假或类似情况时打印一条日志消息。当然,您可以调整它以使用您喜欢的任何日志记录框架,而不是打印到标准输出。
然后,您可以使用现有谓词并将它们包装在对此函数的调用中:
Predicate<String> notNull = loggingPredicate("notNull", input -> (input != null));
Predicate<String> notEmpty = loggingPredicate("notEmpty", input -> (input.trim().length() > 0));
然后像以前一样使用notNull
和notEmpty
。每次评估其中一个时,您都会收到一条日志消息。