As a primitive version of Optional
*, Java 1.8 provides OptionalInt
, OptionalLong
and OptionalDouble
.
But I cannot find the equivalent OptionalBoolean
class.
Are there any technical reasons against having an OptionalBoolean
?
*
An Optional
may or may not have the presence of a value, is used as an alternative to null
.
This quote explains the considerations behind having primitive streams. I'm assuming the same applied to primitive Optionals. In short, primitive streams (and probably Optionals as well) were created for performance reasons. They didn't create them for all 8 primitive types to reduce code duplication and interface pollution.
Quoting the words of Brian Goetz in the lambda mailing list:
More generally: the philosophy behind having specialized
primitive streams (e.g., IntStream) is fraught with nasty tradeoffs.
On the one hand, it's lots of ugly code duplication, interface
pollution, etc. On the other hand, any kind of arithmetic on boxed ops
sucks, and having no story for reducing over ints would be terrible.
So we're in a tough corner, and we're trying to not make it worse.
Trick #1 for not making it worse is: we're not doing all eight
primitive types. We're doing int, long, and double; all the others
could be simulated by these. Arguably we could get rid of int too, but
we don't think most Java developers are ready for that. Yes, there
will be calls for Character, and the answer is "stick it in an int."
(Each specialization is projected to ~100K to the JRE footprint.)
Trick #2 is: we're using primitive streams to expose things that are best done in the primitive domain (sorting, reduction) but not
trying to duplicate everything you can do in the boxed domain. For
example, there's no IntStream.into(), as Aleksey points out. (If there
were, the next question(s) would be "Where is IntCollection?
IntArrayList? IntConcurrentSkipListMap?) The intention is many streams
may start as reference streams and end up as primitive streams, but
not vice versa. That's OK, and that reduces the number of conversions
needed (e.g., no overload of map for int -> T, no specialization of
Function for int -> T, etc.)
And I should mention that I found that quote in the answer to this question.
boolean
values are often abused as parameters. Effective Java 2nd edition warns against abuse of booleans. They often lead to badly readable code if they are not for actual boolean true/false arguments. Instead, Joshua Bloch - the writer - tries to convince people to use double valued enum
's:
Prefer two-element enum
types to boolean
parameters. It makes your code easier to read and to write, especially if you're using an IDE that supports autocompletion. Also it makes it easy to add more options later.
Most OptionalBoolean
instances would probably be used incorrectly. This is a good reason for not including one. But I cannot say - only Oracle can - if this is the reason why it is not in there.
Apart for the desire to reduce the magnitude of the combinatorial explosion of primitive type specialisation classes I suspect one major reason for the absence of an OptionalBoolean
is that the advantage of such a class is much smaller than the advantage of specialisations for the numeric types.
The reason for why the advantage is smaller is that there are only two different values of the type boolean
. Because of this, most of the time you only get two object of type Boolean
. Those two are cached as Boolean.TRUE
and Boolean.FALSE
and reused in most cases, e.g. when boolean
s are auto-boxed. Numeric wrapper types have a number of cached objects for a small range of values, for other values a new object has to be allocated every time a primitive value is stored in a generic container such as Optional
.
So an Optional<Boolean>
object is almost as efficient as an OptionalBoolean
would be since no new Boolean
have to be allocated to put an unboxed boolean
into it.
I could also be useful to have two cashed Optional<Boolean>
available somewhere in the standard library, as Optional.TRUE/FALSE
perhaps. I don't know the reason for why there isn't.
Just to be complete about that: There is indeed an OptionalBoolean
in Java 8, but not where you would expect it: it is com.sun.javafx.scene.control.behavior.OptionalBoolean
.
But, while JavaFX is nowadays a fixed component of Java, it is not advisable to use it outside of JavaFX stuff.
Apart from that, its interface is completely different from the ones you have in java.util.*
.