· java,mashup

inspired by Java Champion Mohamed Taman

Original article: Do you use the Optional class as it should be?

=> 25+ recipes to use Optional class effectively which is not optional

Agenda

  1. How to survive from null pointer exceptions (NPE)
  2. What to return/set when there is no value present?
  3. How to consume optional values effectively?
  4. How to avoid Optional anti-patterns?
  5. How to use Optional professionally?

❔❓ Question #1: oh, I am getting null even when I use Optional?

👉Code recipe #1

//Avoid

Never assign Null to an optional variable.

//Prefer

Initialize an empty() optional variable and do not use null.

👉Code recipe #2

//Avoid

Never call Optional.get() directly to get the value.

//Prefer

Check the value with Optional.isPresent() before calling Optional.get().

👉Code recipe #3

//Avoid

Don't use null directly when you have an Optional & need a null reference.

//Prefer

Use Optional.orElse(null) to return null.

❔❓ Question #2: What to do when no value is present? ☹

👉 Code recipe #4

// Avoid

Don't use isPresent()-get() pair for setting/returning a value.

// Prefer

Use Optional.orElse() as an elegant alternative to set/return an already-constructed default object.

👉 Code recipe #5

//Avoid

Don't use orElse() for setting/returning a computed value.

(Don't use neither isPresent/get).

//Prefer

Performance matters, use Optional.orELseGet() for setting/returning a computed value.

👉 Code recipe #6

//Avoid

Don't throw java.util.NoSuchElementException when there is no value using isPresent()-get().

//Prefer

Throw a java.util.NoSuchElementException exception via an elegant alternative orElseThrow().

// or Prefer

Throw an explicit exception via orElseThrow(Supplier

 exceptionSupplier).

❔❓ Question #3: How to consume Optional effectively? 👌

👉 Code recipe #7

//Avoid

Don't use isPresent()-get() to do nothing if value is not present.

//Prefer

Use ifPresent() to consume Optional value if present or do nothing if not.

👉 Code recipe #8

//Avoid

Don't use isPresent()-get() to execute an Empty-Based action if value is not present.

//Prefer

Use ifPresentOrElse() to consume Optional value if present or execute an empty based action if not.

👉 Code recipe #9

//Avoid

Don't use isPresent()-get() to set/return the other Optional when no value is present.

//Prefer

// or Prefer

👉 Code recipe #10

//Avoid

Don't use isPresent()-get() with Lambdas

Example 1

// also avoid

Don't do this, it is breaking the chain.

// Prefer

Optional.orElse()/orElseXXX() are perfect with Lambdas.

// also Avoid

Don't check for value to throw an exception.

Example 2

//Prefer

Use .orElseThrow with lambdas.

👉 Code recipe 11

//Avoid

Don't overuse Optional by chaining its methods for the single purpose of getting value.

//Prefer

Avoid this practice and rely on simple and straightforward code.

❔❓ Question #4: How can I use Optional while designing my APIs? 🙇‍♂️

👉 Code recipe #12

//Avoid

Do NOT declare any field of type Optional.

Because it breaks serialization, it wastes memory heap space, and because Optional is to prevent null values or Entity fields can be null.

//Prefer

Optional doesn't implement Serializable. It is not intended for use as a property of a Java Bean.

👉 Code recipe #13

//Avoid

Do NOT use Optional in contructors arguments.

It's nonsense, because Optional means it might exist or not WHEN you RETURN it as a type, NOT when you pass it.

//Prefer

Optional is not intended for use in constructors' arguments.

If you wanna check the nullability, do it in a getter with Optional.ofNullable().

👉 Code recipe #14

//Avoid

Using Optional in setters is another anti-pattern.

Same rule than constructors parameters.

//Prefer

Do NOT use Optional in setters arguments.

Concentrate your focus on the getter.

👉 Code recipe #15

//Avoid

Using Optional in methods arguments is another common mistake.

//Prefer

Do NOT use Optional in methods arguments.

// also Prefer

Also, prefer to rely on NullPointerException.

// also Prefer

Also, prefer to avoid NullPointerException and use IllegalArgumentException or other exceptions.

How to use this? This is very easy:

👉 Code recipe #16

//Avoid

Do not use Optional to return empty Collections or Arrays.

// Prefer

Rely on Collections.emptyList(), emptyMap(), emptySet().

👉 Code recipe #17

//Avoid using Optional in Collections.

// Prefer

Do not introduce another layer into your Map, it is costly, and it strikes performance.

// Prefer

You can also rely on other approaches, such as

  • containsKey
  • () method
  • Trivial implementation by extending HashMap
  • Java 8 computeIfAbsent() method
  • Apache Commons DefaultedMap

// Avoid, this is even worse

This strikes performance.

👉 Code recipe #18

Use Optional.ofNullable() instead of Optional.of()

//Avoid

//Prefer

Use Optional.of() instead of Optional.ofNullable() for constructed values (like constants).

//Avoid

//Prefer

👉 Code recipe #19

//Avoid

Avoid Optional

 and choose a non-generci Optional.

//Prefer

To avoid boxing and unboxing, use non-generic Optional.

❔❓ Question #5: I like Optional, what can I do more?

👉 Code recipe #20

There is no need to unwrap Optionals for asserting equality.

//Avoid

//Prefer

👉 Code recipe #21

Avoid using identity-sensitive operations on Optionals.

//Avoid

//Prefer

👉 Code recipe #22

//Avoid

Avoid rejecting wrapped values on .isPresent().

//Prefer

Reject wrapped values based on a predefined rule using .filter().

👉 Code recipe #23

//Avoid

Return a boolean if the Optional is empty via .isPresent() if using Java 11.

//Prefer

Return a boolean if the Optional is empty via .isEmpty().

👉 Code recipe #24

//Avoid

Don't use isPresent() to check the values first then transform it.

//Prefer

Use .Map() and .flatMap() to transform values.

Example 1

//Prefer

Use .Map() to transform values.

Example 2

//Avoid

//Prefer

//Prefer

Use .flatMap() to transform values.

//Avoid

//Prefer

👉 Code recipe 25

Do we need to chain the Optional API with STream API?

//Avoid

//Prefer

Use Optional.stream to treat the Optional instance as a Stream.

Also we can convert Optional to List