3

有一个称为 validate 的方法,它作为输入接受一个实例Option和一个Predicate- 两个参数(是的,我知道Option应该作为参数传递,但这是简化的现实世界场景。现在,如果Option是空的,我需要抛出NotFoundException。当它有一个与传递的值不匹配的值,Predicate它应该失败,ForbiddenException如果它有值并且它与谓词匹配,则不会发生任何事情。

所以这将是:

                Option, Predicate
                     /\
          isEmpty() /  \ isDefined()  
                   /    \
            throw NFE    matches(Predicate)
                        / \
                    no /   \ yes 
                      /     \
                throw FE     end

我有一些解决方案,但希望潜在的回答者清楚地回答这个问题;)如果两个测试都失败,我的问题是第一个例外。如果我可以期待任何东西,我期待一个优雅的解决方案;)允许所有 vavr 存在(Either,,,Validation.. Try

其中一个想法是使用 double Option

Option
  .of(o.getOrElseThrow(NotFoundException::new))
  .filter(p)
  .getOrElseThrow(ForbiddenException::new);

但这似乎有点尴尬。

这里可以找到示例项目。

4

2 回答 2

5

在我看来,最好的选择是创建可读的代码,在这种情况下,这意味着使用两个if语句:

if (!o.isPresent()) throw new NotFoundException();
if (!p.test(o.get())) throw new ForbiddenException();

对于将来需要维护此代码的人来说,它简单、易读且直接。

如果您仍然想以某种功能性的风格进行操作:

o.orElseThrow(NotFoundException::new);
o.filter(p).orElseThrow(ForbiddenException::new);

使用 Java 9:

o.ifPresentOrElse(
    t -> if (!p.test(t)) throw new ForbiddenException(), 
    () -> throw new NotFoundException());
于 2017-11-17T00:44:28.660 回答
3

这将是解决方案Optional(没有时间检查vavr,但应该足够接近)

public static <T> void validate( Optional<T> optional, Predicate<T> pred ) throws NotFoundException, ForbiddenException {
    if ( !pred.test( optional.orElseThrow( NotFoundException::new ) ) )
        throw new ForbiddenException();
}

ForbiddenException不幸的是,不知道有什么更漂亮的方法来抛出它。

如果您想要一个功能齐全的解决方案,您将需要一个Optional

Optional.of( 
    pred.test( 
       option.orElseThrow( NotFoundException::new ) 
    ) 
).filter( b -> b ).orElseThrow( ForbiddenException::new );

异常以正确的顺序抛出,因为我们只在检查Predicate之后option检查。

于 2017-11-16T20:55:12.513 回答