I would like to implement lazy field initialization (or deferred initialization) without an if statement and taking advantage of lambdas. So, I would like to have the same behavior of the following Foo
property but without the if
:
class A<T>{ private T fooField; public T getFoo(){ if( fooField == null ) fooField = expensiveInit(); return fooField; } }
Ignore the fact that this solution is not guaranteeing safe use for: 1) multi-threading; 2) null
as a valid value of T
.
So, to express the intention that the initialization of the fooField
is deferred until its first use I would like to declare the fooField
of the type Supplier<T>
such as:
class A<T>{ private Supplier<T> fooField = () -> expensiveInit(); public T getFoo(){ return fooField.get(); } }
and then in the getFoo
property I would just return fooField.get()
. But now I want that next invocations to getFoo
property avoid the expensiveInit()
and just return the previous T
instance.
How can I achieve that without using an if
?
Despite naming conventions and replacing the ->
by =>
, then this example could be also considered in C#. However, NET Framework version 4 already provides a Lazy<T>
with the desired semantics.
Lambdas allows Java to be lazy, as they represent a function to be executed that can be passed around and will only be evaluated when required. The examples below are pretty simple but should demonstrate the order of execution, showing that the lambdas are not executed straight away.
Lazy initialization is an excellent performance optimization technique, allowing you to defer the initialization of objects that consume significant CPU and memory resources until you absolutely need them. Take advantage of lazy initialization to improve the performance of your apps.
The answer is it depends. I have seen cases where using a lambda was slower and where it was faster. I have also seen that with newer updates you get more optimal code.
Lazy initialization of an object means that its creation is deferred until it is first used. (For this topic, the terms lazy initialization and lazy instantiation are synonymous.) Lazy initialization is primarily used to improve performance, avoid wasteful computation, and reduce program memory requirements.
Within your actual lambda, you can simply update the fooField
with a new lambda, such as:
class A<T>{ private Supplier<T> fooField = () -> { T val = expensiveInit(); fooField = () -> val; return val; }; public T getFoo(){ return fooField.get(); } }
Again this solution is not thread-safe as is the .Net Lazy<T>
, and does not ensure that concurrent calls to the getFoo
property return the same result.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With