Created by Todd Ginsberg
for CJUG
2016-06-02
"Our intention was to provide a limited mechanism for library method return types where there needed to be a clear way to represent "no result", and using null for such was overwhelmingly likely to cause errors."
new ArrayList<String>().stream().findFirst();
public interface Map<K,V> {
// ...
default Optional<V> getOptionally(K k) {
// ...
}
}
Map<String, String> map = new HashMap<>();
map.put("A",null);
// Both look the same - no difference between not present and null.
map.getOptionally("A");
map.getOptionally("B");
value | isEmpty() | isPresent() | .get() |
---|---|---|---|
not null | false | true | value |
null | true | false | NoSuchElementException |
Optional<String> text = Optional.ofNullable("Hello, world!");
Optional<String> text = Optional.of(somethingThatIsntNull);
Optional<String> text = Optional.of(null);
// -> NullPointerException
// Yes
public Optional<Customer> getCustomerById(long id);
// No
public Optional<List<Customer>> getCustomersForMonth(final YearMonth when);
// Prefer:
public List<Customer> getCustomersForMonth(final YearMonth when);
// -> Collections.emptyList();
Optional<String> text = service.getText();
if(text.isPresent()) {
System.out.println(text.get());
} else {
System.out.println("Hello, world!");
}
String text = service.getText();
if(text != null) {
System.out.println(text);
} else {
System.out.println("Hello, world!");
}
"In retrospect, we should have called get something like getOrElseThrowNoSuchElementException or something that made it far clearer that this was a highly dangerous method that undermined the whole purpose of Optional in the first place. Lesson learned."
Optional<String> text = service.getText();
System.out.println(text.orElse("Hello, world!"));
Optional<String> text = service.getText();
text.ifPresent(this::doSomethingWithText);
Optional<String> text = service.getText();
System.out.println(text.orElseThrow(NoSuchElementException::new));