只是为了完整性,“几个变量”的情况确实是可能的,尽管一点也不优雅。例如,对于变量o
、p
和q
:
Optional.ofNullable( o ).orElseGet(()-> Optional.ofNullable( p ).orElseGet(()-> q ) )
请注意,注意orElseGet()
,o
和p
不是q
变量而是表达式昂贵或具有不希望的副作用的情况。
在最一般的情况下coalesce(e[1],e[2],e[3],...,e[N])
coalesce-expression(i) == e[i] when i = N
coalesce-expression(i) == Optional.ofNullable( e[i] ).orElseGet(()-> coalesce-expression(i+1) ) when i < N
这会生成过长的表达式。但是,如果我们试图移动到一个没有 的世界null
,那么v[i]
很可能已经属于类型Optional<String>
,而不是简单String
的 。在这种情况下,
result= o.orElse(p.orElse(q.get())) ;
或者在表达式的情况下:
result= o.orElseGet(()-> p.orElseGet(()-> q.get() ) ) ;
此外,如果您也转向函数式声明风格,o
, p
, 并且q
应该是如下类型Supplier<String>
:
Supplier<String> q= ()-> q-expr ;
Supplier<String> p= ()-> Optional.ofNullable(p-expr).orElseGet( q ) ;
Supplier<String> o= ()-> Optional.ofNullable(o-expr).orElseGet( p ) ;
然后整体coalesce
简化为o.get()
。
举一个更具体的例子:
Supplier<Integer> hardcodedDefaultAge= ()-> 99 ;
Supplier<Integer> defaultAge= ()-> defaultAgeFromDatabase().orElseGet( hardcodedDefaultAge ) ;
Supplier<Integer> ageInStore= ()-> ageFromDatabase(memberId).orElseGet( defaultAge ) ;
Supplier<Integer> effectiveAge= ()-> ageFromInput().orElseGet( ageInStore ) ;
defaultAgeFromDatabase()
, ageFromDatabase()
, 并且ageFromInput()
已经很Optional<Integer>
自然地返回了。
然后如果我们对 a 感到满意,coalesce
就变成effectiveAge.get()
或简单地说。effectiveAge
Supplier<Integer>
恕我直言,在 Java 8 中,我们将看到越来越多的代码结构是这样的,因为它同时非常易于解释和高效,尤其是在更复杂的情况下。
我确实想念一个只Lazy<T>
调用Supplier<T>
一次但很懒惰的类,以及Optional<T>
(即Optional<T>
-Optional<T>
运算符,甚至Supplier<Optional<T>>
)定义的一致性。