Why is there no Optional.mapToInt () option in Java8?

In Java8 threads, I can use the mapToInt method to create an IntStream that will return OptionalInt for some actions (e.g. findFirst ). Why is Optional nothing like this?

 int i = Stream .of("1") // just as an example .mapToInt(Integer::parseInt) // mapToInt exists for streams .findFirst() // this even returns an OptionalInt! .getAsInt(); // quite handy int j = Optional .of("1") // same example .map(Integer::parseInt) // no mapToInt available .get().intValue(); // not as handy as for streams 
+6
source share
3 answers

Optionals appears to have several additional methods in Java-9. However, mapToInt unlikely to be added. I discussed this issue a few days ago in core-libs-dev. Here's Paul Sandoz's answer :

I don’t want to go there, my answer is converted Optional* to *Stream . The argument for adding mapOrElseGet (note that primitive options return U ) is that other functionality can be compiled from it.

And later :

I think it's normal to foul OptionInt, etc. with an option, but I want to avoid this for another direction.

In general, I think this is reasonable. The goal of primitive threads is to improve performance when processing many primitive values. However, for Optional performance gain when using a primitive value is rather insignificant, if any (there are much more chances compared to threads that the additional box will be optimized by the JIT compiler). In addition, although the Valhalla project will not be displayed in Java-9, it is gradually advancing, and it is possible that in Java-10 we will finally see generics-over-primitives, so these primitive options will become completely unnecessary. In this context, adding more interoperability between Object Optional and primitive OptionalInt seems unnecessary.

+6
source

It makes sense to have specializations in the Stream API, since a stream can represent bulk operations that process millions of elements, so the performance impact can be significant. But, as far as I know, even this decision was not without controversy.

For Optional , carrying no more than one element, the performance impact does not justify additional APIs (if it ever has an impact). It is not clear if OptionalInt really needed, etc.

As for convenience, I can not understand. The following works:

 int j = Optional.of("1").map(Integer::parseInt).get(); 

your suggestion is to add another API that allows you to rewrite the above statement as

 int j = Optional.of("1").mapToInt(Integer::parseInt).getAsInt(); 

I don’t see how it enhances convenience ...

But following the logic, with Java 9, you can write

 int j = Optional.of("1").stream().mapToInt(Integer::parseInt).findFirst().getAsInt(); 

which enhances this "convenience" even more ...

+6
source

The following also works pretty well:

 int j = Optional .of("1") .map(Integer::parseInt) .map(OptionalInt::of) // -> Optional<OptionalInt> .orElse(OptionalInt.empty()) // -> OptionalInt .getAsInt(); 

The trick is to map Optional<Integer> to Optional<OptionalInt> and then expand the internal OptionalInt . Thus, as for Optional , the int primitive is not involved, so it works with Java generalizations.

One of the advantages of this approach is that it does not need auto-boxing. This is an important point for me, since we included warnings for autoboxing in our project, first of all, to prevent unnecessary packing and unpacking operations.

I came across this problem and solution when implementing an open method that returns OptionalInt , where the implementation uses another method that returns Optional<Something> . I did not want to return Optional<Integer> from my public method, so I was looking for something like Optional.mapToInt like you.

But after reading the answers of Holger and Tagir Valeev , I agree that it is quite reasonable to omit such a method in the JDK. There are ample alternatives available.

0
source

Source: https://habr.com/ru/post/1232800/


All Articles