我想在没有if语句的情况下实现惰性字段初始化(或延迟初始化)并利用lambdas.所以,我想具有以下Foo
属性的相同行为,但没有if
:
class A<T>{
private T fooField;
public T getFoo(){
if( fooField == null ) fooField = expensiveInit();
return fooField;
}
}
Run Code Online (Sandbox Code Playgroud)
忽略这个解决方案不能保证安全使用的事实:1)多线程; 2)null
作为有效值T
.
因此,为了表达初始化fooField
被推迟到第一次使用的意图,我想声明fooField
类型Supplier<T>
如下:
class A<T>{
private Supplier<T> fooField = () -> expensiveInit();
public T getFoo(){
return fooField.get();
}
}
Run Code Online (Sandbox Code Playgroud)
然后在getFoo
财产中我会回来fooField.get()
.但是现在我想要对getFoo
属性的下一次调用避免expensiveInit()
并且只返回前一个T
实例.
如何在不使用的情况下实现这一目标if
?
尽管命名约定并替换了->
by =>
,但是这个例子也可以在C#中考虑.但是,.NET Framework版本4已经提供了Lazy<T>
所需的语义.
我正在使用Async Http Client 库(使用 Netty)向 RESTful API 发出异步 Http Get 请求。由于我想保留非阻塞行为,因此我将CompletableFuture<T>
作为 Http Get 请求的结果返回的实例。因此,在 RESTful API 端点返回一个 Json 数组的地方,我返回一个CompletableFuture<T[]>
.
然而,根据 Erik Meijer 对编程中的四种基本效果所做的分类,我认为这Stream<T>
更适合于发出异步 Http Get 请求并返回 Json 数组的 Java 方法的结果。在这种情况下,我们可以将Stream<T>
视为Observable<T>
等价物,它是返回许多值的异步计算的结果。
所以,考虑到这resp
持有响应,那么我可以得到CompletableFuture<Stream<T>>
如下:
CompletableFuture<T[]> resp = …
return resp.thenApply(Arrays::stream);
Run Code Online (Sandbox Code Playgroud)
但是,我想知道如何将 the 转换CompletableFuture<Stream<T>> resp
为 a Stream<T>
,而无需等待计算完成(即我不想在get()
调用时阻塞)?
我希望得到与以下表达式相同的结果,但不阻塞get()
:
return resp.thenApply(Arrays::stream).get();
Run Code Online (Sandbox Code Playgroud)