Reputation: 327
I am using this code:
A a = aMap.contains(key) ? aMap.get(key) : createAExpensively(key);
I believe that Java is lazy so if aMap.contains(key))
then the createAExpensively()
function is never called.
Then, I stumbled onto the Map.getOrDefault()
method. If we instead use:
A a = aMap.getOrDefault(key, createAExpensively(key));
is Java still lazy in calling the createAExpensively()
function?
It seems that Java will first create the object A
and pass it as a method parameter, based on this question, but I'm not totally sure.
If Java is not lazy when using Map.getOrDefault()
, what is the point of that method?
Upvotes: 1
Views: 2208
Reputation: 124646
Is Java still lazy in calling the
createAExpensively()
function? [in.getOrDefault(key, createAExpensively(key))
]
Function parameters are evaluated (from left to right) before actually calling the function. So createAExpensively(key)
will be evaluated before calling getOrDefault
. This behavior is also known as applicative order evaluation strategy.
If Java is not lazy when using
Map.getOrDefault()
, what is the point of that method?
It's useful when the default value is not expensive to create,
for example when it's an already computed value or constant.
In that case the Map.getOrDefault(...)
call allows a more compact syntax than the ternary operator.
If the default value is expensive to compute,
and if you actually want to put the computed value in the map,
then as of Java 8,
you can use computeIfAbsent
:
A a = aMap.computeIfAbsent(key, k -> createAExpensively(k));
Upvotes: 2
Reputation: 415
Java is not lazy at all. You are using conditional operator to check whether aMap.contains(key)
. If this is true it will never call createAExpensively(key)
but aMap.get(key)
Upvotes: 2
Reputation: 44834
It is not lazy at all.
This code
A a = aMap.contains(key) ? aMap.get(key) : createAExpensively(key);
evaulates to
if (aMap.contains(key))
{
a = aMap.get(key);
}
else
{
a = createAExpensively(key);
}
Upvotes: 1
Reputation: 131525
This is called "short-circuit evaluation" rather than lazy evaluation: The JVM is not deferring evaluation of createExpensively()
, but rather avoiding it completely if it's not necessary, i.e if the condition holds.
See also the answer to the following question here on StackOverflow:
Java logical operator short-circuiting
Upvotes: 1
Reputation: 198033
It isn't lazy in that case.
The point of the method is that there's lots of times when the default is a constant or something you've already computed anyway. For example, you might use getOrDefault(key, 0)
when you're getting some kind of count and absent keys should be counted as zeroes.
Upvotes: 1