Explain Codes LogoExplain Codes Logo

Difference between Optional.orElse() and Optional.orElseGet()

java
prompt-engineering
best-practices
performance
Alex KataevbyAlex Kataev·Feb 4, 2025
TLDR

Optional.orElse() is quick to act and prematurely computes its argument, which is potentially resource-wasting for CPU-intensive tasks when the Optional is removed later. Meanwhile orElseGet() is more of a wait-and-see type who ensures resource efficiency by deferring its Supplier computation until the Optional is vacant.

String value = Optional.of("Hello, World!").orElse(computeIntensiveOperation()); // "Hello, World!" is here, but "computeIntensiveOperation()" ran anyway... what a waste! String efficientValue = Optional.of("Hello, World!").orElseGet(() -> computeIntensiveOperation()); // "Hello, World!" remains with no unnecessary computations, the way life should be!

Always go for orElseGet() when you're dealing with heavy-lifting operations. Stick to orElse() when it's just a walk in the park or static fallbacks.

Calculating the performance checks

orElse() and orElseGet() are like two grocery store cashiers with markedly different efficiency levels. The choice between Johnny orElse() and Suzy orElseGet() can have significant impacts on the store's bottom line.

  • State Reliant Logic: If you've got logic that changes the state, orElseGet() makes that transaction conditional and avoids accidental oversights.
Optional.of("Employee of The Month").orElseGet(() -> { logStorePerformance(); // Logs only if the award is unclaimed, keeps the boss's inbox clean return "Try Again Next Month"; });
  • Network/Disk Operations: When fallbacks involve long-distance calls or disk reading, orElseGet() prevents these time-consuming operations unless it's last-minute.

  • Synchronized Routines: In synchronized routines, when timing matters, orElseGet() could be beneficial in calming the racing threads.

In summary, sticking with orElseGet() is like preserving electricity by turning off unused appliances and leads to optimal application performance.

Best practices - making the right choice

Would you always drive to the corner shop even if it's just a minute's walk away? Or would you prefer to take the car only when the grocery list is long and heavy? Understanding the trade-offs and consequences of our choices can drive us in the right direction:

orElse() in action

  • Static Defaults: For default values that don't burn much CPU, orElse() is perfectly suitable.
final String regularCustomer = "John Doe"; String customer = Optional.ofNullable(customerName).orElse(regularCustomer); // Static value, doesn't heat the CPU
  • Fast and Light Operations: Swift operations or low-complexity values aren't taxing on the JVM, making orElse() a no-brainer choice.

Why orElseGet()?

  • Wait and Watch: Specifically when the fallback value requires complex computations, you'll be thankful to orElseGet() for instant savings.
// Store customer database is huge, we'll wait String shoppingCartOwner = Optional.ofNullable(customerID).orElseGet(StoreDatabase::getCustomerRecord);
  • Selective Logging: Logs only in the void of the Optional, leaving you with cleaner and more meaningful logs.

The art of picking one

Unlike your favorite ice cream flavor, choosing between orElse() and orElseGet() is not always a straightforward task. It's more like a scale balance, where readability competes with efficiency. Choose readability when the performance cost of a non-lazy evaluation is trivial, and let efficiency take center stage when facing heavyweight computations.

Unveiling their real-world counterparts

Let’s map orElse() and orElseGet() to real-world scenarios for a more relatable understanding:

orElse() is like mass printing a report that might or might not be read — an upfront resource commitment. orElseGet(), in contrast, is like printing only when the report is requested — optimizing resource usage.

Energy Efficient Appliances

Operating orElse() is similar to leaving your lights and appliances switched on even when not required, wasting energy. orElseGet(), on the other hand, is like energy-efficient appliances that conserve energy until activated.

Emergency Services Dispatch

orElse() is like dispatching paramedics at the slightest hint of an emergency. Meanwhile, orElseGet() is like a more resource-efficient approach, deploying emergency services only when the situation is confirmed.