Java lambda表达式:组合模式改进

时间:2018-04-01 13:53:26

标签: java lambda java-8

我在网上发现了这篇文章:https://gtrefs.github.io/code/combinator-pattern/。作者描述了网站上用户询问姓名,电子邮件和年龄的验证过程。如果验证过程失败,它将输出错误消息。

在我看来,这种方法非常适合保持代码可以理解。但是,他的解决方案有一个缺点。最后,这种模式当时只产生了一个错误。当名称为空且电子邮件不包含@ -sign时,它会打印"名称为空"仅

基于代码段

static UserValidtion all(UserValidation... validations){ 
  // Your code here 
}

在文章的最后,我尝试创建一个生成这些错误列表的方法。

但我提出了一个非常糟糕的解决方案,它在界面UserValidation中打印出原因。 Altough,它产生一个NullPointerException(在这里你可以执行我的代码:http://tpcg.io/WSI2u3):

UserValidation.java

static UserValidation all(UserValidation... validations){
        return user -> 
        {
            Arrays.stream(validations).forEach(validation -> {
                //returns the reason  why one of the user inputs is not valid
                System.out.println(validation.apply(user).getReason()); 
                //I don't know how to combine the reasons here to have a proper output in the main. 
            });

            return null;
        };
    }

Main.java

public class Main {

    public static void main(String[] args) {

        UserValidation rules[] = {UserValidation.nameIsNotEmpty(),UserValidation.eMailContainsAtSign()};
        UserValidation validation = UserValidation.all(rules);
        User gregor = new User("", 30, "mailmailinator.com");
        ValidationResult result = validation.apply(gregor);     
        result.getReason().ifPresent(System.out::println); 

    }
}

我对lambda表达式没有任何意义,但我尝试了很多,并不适合这种方法。 这就是我试过的:

  • 在UserValidation接口中添加了一个静态ArrayList,以保存传递的原因。没有用,因为main方法中的调用只接受UserValidation-Object。
  • 将一个ArrayList添加到ValidationResult接口以存储原因列表。因为我无法一次访问所有原因而无法正常工作。

提前致谢。

1 个答案:

答案 0 :(得分:0)

我在您的代码中做了几处更改

    static Function< User, List<ValidationResult> > all(UserValidation... validations){
    return user -> 
    {
        return Arrays.stream(validations).map(validation -> 
            validation.apply(user)
        ).filter(vr-> !vr.isValid())
        .collect(Collectors.toList());

    };
}

并更改了主要内容以显示验证错误。

        UserValidation rules[] = {UserValidation.nameIsNotEmpty(),UserValidation.eMailContainsAtSign()};
    Function< User, List<ValidationResult> > validation = UserValidation.all(rules);
    User gregor = new User("", 30, "mailmailinator.com");
    List<ValidationResult> result = validation.apply(gregor);

    result.forEach(item -> System.out.println(item.getReason().get()));

看起来它可以按照您的要求工作。