【发布时间】:2015-06-17 01:41:40
【问题描述】:
我正在将一些代码移至 java8,尝试(有时强迫自己)使用流和 lambda,但我对它们还不满意。
我在一个类中有一些方法可以验证一个业务对象。每个方法看起来都像
Optional<Fail> validate1(BusinessObject bo)
其中 Fail 是一个以某种方式描述错误的枚举,如果没有错误,则该方法返回 Optional.empty()。我不需要收集所有错误,而是返回第一个错误,而不执行以下验证。
我正在做的是
//first convert methods to suppliers
Supplier<Optional<Fail>> validate1= () -> validate1(bo);
Supplier<Optional<Fail>> validate2= () -> validate2(bo);
Supplier<Optional<Fail>> validate3= () -> validate3(bo);
//then some stream magic
return Stream.of(validate1, validate2, validate3)
.map(Supplier::get)
.filter(f -> f.isPresent())
.findFirst()
.orElse(Optional.empty()); //without the orElse, no error would return
// Optional(Optional.empty())
// instead of Optional.empty()
它有效,它完成了工作,它不执行不必要的方法,它清晰易读(如果 Optional.orElse 被命名为 getOrElse,它会更清晰,但我无法做到)。我想知道的是,这是否是一种合理的方式来做我想做的事,这段代码是否会被认为是“好的风格”或“惯用的 java8”,或者我是否在滥用 Stream 或 Optional,或者遗漏了一些明显的东西。
返回第一个非空 Optional 或返回第一个空 Optional(如果它们都是空的)的想法看起来很笼统,足以认为有一种官方方法可以做到这一点,我脑后的某些东西正在大喊“Monads!”,但是我对 Haskell 的无知几乎是完美的,所以我不知道。
【问题讨论】:
-
看起来相当合理的代码风格。
-
如果我是你,我可能会使用
Stream.of(validate1(bo), validate1(bo), validate1(bo))而不是使用供应商。 -
@Jatin 会立即调用所有验证方法。 OP 只想在需要时调用它们。
-
@Misha 哎呀。是的。一个非常有效的观点。
-
见this answer;它与您的问题的代码基本相同,但更简洁,通过在
.findFirst()之前使用.map(Optional::get),您可以保存orElse部分......
标签: lambda functional-programming java-8