Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8277886

Suggestion to add Optional<T> find(... key) methods to all collections




      I've been thoroughly developing for Java for many years and watching the language evolve over the time I started noticing the trend the language has been heading. Hence, here is a proposal from me that would make the language greatly benefit and let it continue to grow.

      One of the main problems that has been plaguing the language throughout its entire existence is the `null` value. Analogous to the ancient C/C++ `nullptr`, `null` represents non-existant value passed over to a given method or just a variable. Performing any operations upon a `null` value causes NullPointerException, which halts the execution at runtime, mostly at unexpected moments. The modern solution given to this problem is the Optional type added in Java 8.

      Optional type forces the developer to always handle the case when the value does not exist. A codebase that contains only Optionals rather than `null`s can easily remove most of the `null` checks from the rest of the code, making it easier to read, easier to maintain, and more performant.

      Optional type is a great step in a right direction, however, support for it in the rest of Java core libraries has been minimal - only Stream API greatly benefits from it. My suggestion, as a step towards more modern and beautiful Java is to modify the Collection, Map and many other util API in Java to have a much better support for Optional type.

      Here is a List example:
      Using `E value = list.get(0);` on an empty list will cause IndexOutOfBoundsException. A much more elegant way would be to add a `Optional<E> value = list.find(0);`, which will return a `Optional.empty()` in case supplied index is not present in the list. Currently such a case would require a `list.isEmpty()` check or a try-block with the exception caught, which is easy to forget to add or could be unexpected and forgotten intentionally ("Oh, this collection should never have any issues with this index! I need not to do a check here...").

      Here is a Map example:
      Using `int len = map.get("a").length();` on a `Map<String, String>` with no key "a" present will cause a NullPointerException because `map.get("key")` gives `null`. A much better way to do this would be to force the developer to handle the case using `int len = map.find("a").map(String::length).orElse(0)`. In this case the code is guaranteed to never cause any previous issues (Optional does not allow nulls, so a null value will equate to `Optional.empty()`). Currently, it is possible to have this code run using `Optional.ofNullable()`: `int len = Optional.ofNullable(map.find("a")).map(String::length).orElse(0)`. It is, however, quite easy to forget to wrap it like so in the newly written code, or to forget an old piece of code that needed to be refactored - an explicit method like `find` would easily remind developers not to forget about these issues.

      I named the method `find` similarly to how Stream API has `findFirst()` and `findAny()`, which are the methods returning Optional. In that case, the usual `get()` counterparts to the new `find()` methods will mean that they will try to get the value without checking if it is present, and their implementation can be easily changed to `this.find(...).get()` in most cases, even rewritten to be default methods in the interfaces.

      As an additional node, some way of forcing normal object values to never be `null` at compile time would be great. Maybe some syntactic sugar for Optional could be added in the future, to make it easier to use and to get the best modern Java.




            Unassigned Unassigned
            webbuggrp Webbug Group
            0 Vote for this issue
            2 Start watching this issue