Working with Optional

1. Creating Optional

MethodDetail
Optional.of(value)Throws NPE if null
Optional.ofNullable(value)Empty if null
Optional.empty()No value

2. Checking Presence

MethodReturns
isPresent()boolean
isEmpty() JAVA 11+boolean
ifPresent(c)void
ifPresentOrElse(c, runnable) JAVA 9+void

3. Getting Values

MethodBehavior
get()Throws if empty (avoid)
orElse(default)Eager default
orElseGet(supplier)Lazy default
orElseThrow()NoSuchElementException
orElseThrow(supplier)Custom exception

4. Throwing Exceptions

Example: orElseThrow

User user = repo.findById(id)
    .orElseThrow(() -> new UserNotFoundException(id));
PatternUse
Specific exceptionService-layer not-found
Default exceptionorElseThrow()

5. Mapping Values

MethodUse
map(fn)Transform if present
flatMap(fn)fn returns Optional

6. Filtering Values

Example: filter

String name = Optional.ofNullable(input)
    .filter(s -> !s.isBlank())
    .map(String::trim)
    .orElse("anonymous");
MethodDetail
filter(p)Empty if predicate false

7. Consuming Values

MethodUse
ifPresent(c)Side-effect when present
ifPresentOrElse(c, r)Side-effect or fallback

8. Chaining Operations

MethodDetail
or(supplier) JAVA 9+Alternative Optional
map / flatMapTransform chain

9. Converting to Stream

MethodResult
opt.stream() JAVA 9+0 or 1 element stream
Use caselist.stream().flatMap(Optional::stream) filters/unwraps

10. Understanding Optional Best Practices

PracticeReason
Use as return typeExpress absence in API
Don't use as fieldNot Serializable; adds overhead
Don't use as parameterPass T or overload
No collectionEmpty collection > Optional<List>

11. Avoiding Optional Misuse

Anti-patternBetter
opt.get() without checkorElseThrow / orElse
if(opt.isPresent()){opt.get()}opt.ifPresent(...)
Optional.of(maybeNull)Optional.ofNullable