Think about the 7 rules of Optional

Overview

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.

7 rules of Optional

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. ..

  1. Never, ever, use null for an Optional variable or return value.
  2. Never use Optional.get() unless you can prove that the Optional is present.
  3. Prefer alternatives to Optioal.isPresent() and Optional.get().
  4. It’s generally a bad idea to create an Optional for the specific purpose of chaining methods from it to get a value.
  5. If an Optional chain has a nested Optional chain, or has an intermediate result of Optional, it’s probably too complex.
  6. Avoid using Optional in fields, method parameters, and collections.On a related note, I thought of another rule after I presented the session:
  7. Don’t use an Optional to wrap any collection type (List, Set, Map). Instead, use an empty collection to represent the absence of values.

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)".

Document

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

Optional orElse Family

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

Cases where you want to actively use Optional.orElseGet

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?".

So why did you use it?

--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.

Optional is inferior to code that just does null checking

  1. Optional is an object, creating one extra Optional object that you don't need to use with a simple null check
  2. Code using Optional makes it impossible to execute detailed steps in the debugger.
  3. Optional can only be used with Java 8 or later

amendment

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.


Cases where the ternary operator & null check is more suitable than the easy use of Optional

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"

reference

Recommended Posts

Think about the 7 rules of Optional
Think about the combination of Servlet and Ajax
About the handling of Null
About the description of Docker-compose.yml
About the basics of Android development
About Optional
About the role of the initialize method
Summary about the introduction of Device
About the log level of java.util.logging.Logger
About the version of Docker's Node.js image
What is testing? ・ About the importance of testing
About the operation of next () and nextLine ()
About the initial display of Spring Framework
About the treatment of BigDecimal (with reflection)
About the number of threads of Completable Future
About the mechanism of the Web and HTTP
About the method
About the package
About the official start guide of Spring Framework
About the description order of Java system properties
About the idea of anonymous classes in Java
About next () and nextLine () of the Scanner class
Output about the method # 2
About the StringBuilder class
The world of clara-rules (2)
Commentary: About the interface
About the asset pipeline
About the function double-java
[Grails] About the setting area and the setting items of application.yml
About the usefulness of monads from an object-oriented perspective
Talking about the merits of database bind variables ((1) Introduction)
About selection of OpenJDK
About the problem of deadlock in parallel processing in gem'sprockets' 4.0
About DI of Spring ①
Judgment of the calendar
The world of clara-rules (4)
The world of clara-rules (1)
About DI of Spring ②
The world of clara-rules (3)
About the length method
About the Kernel module
The world of clara-rules (5)
The idea of quicksort
About the authenticate method.
[Technical memo] About the advantages and disadvantages of Ruby
About the map method
About the ancestors method
About form. ○○ of form_with
I learned about the existence of a gemspec file
[Output] About the database
Think about the JAVA = JAVAscript problem (needed in the future)
About @Accessors of Lombok
About the [ruby] operator
About the to_s method.
Summarize the additional elements of the Optional class in Java 9
The idea of jQuery
About the function of Spring Boot due to different versions
About truncation by the number of bytes of String on Android
[Ruby] Questions and verification about the number of method arguments
Have you ever thought about the definition of "bad design"?
About the operation of Java reading party BOF-held monthly since 1998