At the Devoxx US 2017 conference I attended the other day, I learned about the rules for dealing with Optional, so I will write down what I thought about it.
Mr.Stuart Marks (@stuartmarks) "Optional --The Mother of all Bikesheds / Optional_-_The_Mother_of_all_Bikesheds) "was attended. So, 7 rules when using java.util.Optional were introduced. ..
Optional.get()
unless you can prove that the Optional is present.Optioal.isPresent()
and Optional.get()
.Please refer to the materials below (except for Rule 7) for what each means. By the way, present indicates "the state where Optional has a value (≒ Not Empty)", and absolute indicates "the state where Optional has no value (≒ Empty)".
The Devoxx US 2017 version has not been released yet, but it seems that he had a session with the same title at another conference before that, and the material and video are released. We recommend that you read this article, as it contains very useful information for those who are thinking about using Optional or who have recently started using Optional.
Format | Link |
---|---|
Document | https://stuartmarks.files.wordpress.com/2016/09/optionalmotherofallbikesheds3.pdf |
Video | https://www.youtube.com/watch?v=Ej0sss6cq14 |
Twitter hashtag | https://twitter.com/hashtag/DevoxxOptional?src=hash |
Use the get () or Else Family methods to retrieve the values contained in Optional. The get () method throws a runtime exception NoSuchElementException when the Optional object is empty, so you shouldn't use it unless you check with isPresent. Normally, you will use the orElse Family method, or ifPresent (a method that describes the processing to be performed at the time of present with a Lambda expression).
Method | Do absent |
---|---|
orElse(DEFAULT_VALUE) | DEFAULT_Returns VALUE(If you specify a method here, it will be executed by both present and absent.) |
orElseGet(Object::new) | Supplier.get is called and the object created there is returned |
orElseThrow(Exception::new) | Throw an exception |
It was talked about in TL a while ago. (Reference: Use orElseGet () to retrieve the value from Optional) When preparing the value to be returned at the time of absent by method call, You should actively use orElseGet. In this case, the method is called only when absent is used.
orElse
Whenever this line is executed, Collections.emptyList()Is called
.orElse(Collections.emptyList())
orElseGet
Collections only when absent.emptyList()Is called
.orElseGet(Collections::emptyList)
Optional.get() I personally thought that "```Optional.get ()` `` denies the value of Optional and should be deleted." But it turns out that it's not really that easy. First look at the code below.
isPresent&get
final Optional<Bounds> caretBoundsOr = editor.getCaretBounds();
if (caretBoundsOr.isPresent()) {
final Bounds bounds = caretBoundsOr.get();
return new Point2D(bounds.getMinX(), bounds.getMinY() + 20);
}
return null;
It is a process that follows the rule of "check with isPresent and then get". In the case of absent, `return null;`
is the case where you want to rush into "Why are you using Optional if you return null?".
--The library API didn't provide a method to return raw values that weren't Optional ... I had to use the RichTextFX library's CodeArea.getCaretBounds method because it returned Optional. --The orElse Family method could not be used because the object creation was designed to be difficult for library users to call.
As mentioned above, the value is fetched after checking with isPresent (), so it follows the rules of Mr.Marks. However, the Optional isPresent-> get is far from better than just null-checking code.
When I think about it, is it safe to write like this ...
final Optional<Point2D> pointOr
= editor.getCaretBounds()
.map(bounds -> new Point2D(bounds.getMinX(), bounds.getMinY() + 20));
return pointOr.isPresent() ? pointOr.get() : null;
Optional is used together with filter (continue processing to the next operator only when the value matches the condition) and map (convert the value) in the case where not only null check but also subsequent processing is written together. I think it's better.
I thought Mr. Stuart Marks wanted to say that if you write code using Optional like the one below, you can simply use the ternary operator.
That Optional.orElse code
Optional.ofNullable(runScript()).orElse("0").toString()
Using the ternary operator is shorter, easier to understand, and eliminates the need for unnecessary Optional objects.
Code of ternary operator that can do the same
final String script = runScript();
script != null ? script : "0"
Recommended Posts