zli
zli

Reputation: 327

Is Java lazy when passing parameters to a method?

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

Answers (5)

janos
janos

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

Adeel
Adeel

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

Scary Wombat
Scary Wombat

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

einpoklum
einpoklum

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

Louis Wasserman
Louis Wasserman

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

Related Questions