Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

In Java8 streams I can use the mapToInt method to create an IntStream, which will return OptionalInts for some actions (like findFirst). Why isn't there anything similar in Optional?

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
like image 868
slartidan Avatar asked Oct 02 '15 13:10

slartidan


People also ask

What is stream API in Java 8?

Introduced in Java 8, the Stream API is used to process collections of objects. A stream is a sequence of objects that supports various methods which can be pipelined to produce the desired result.

What is the purpose of MAP method of stream in Java 8?

Java 8 Stream's map method is intermediate operation and consumes single element forom input Stream and produces single element to output Stream. It simply used to convert Stream of one type to another.

How many types of streams are available in Java 8?

Java 8 offers the possibility to create streams out of three primitive types: int, long and double. As Stream<T> is a generic interface, and there is no way to use primitives as a type parameter with generics, three new special interfaces were created: IntStream, LongStream, DoubleStream.

What is stream () in Java?

Stream is a new abstract layer introduced in Java 8. Using stream, you can process data in a declarative way similar to SQL statements. For example, consider the following SQL statement. SELECT max(salary), employee_id, employee_name FROM Employee.


2 Answers

Apparently a handful of additional methods will appear in Optionals in Java-9. However it's unlikely that mapToInt will be added. I discussed this problem several days before in core-libs-dev. Here's Paul Sandoz answer:

I don’t wanna go there, my response is transform Optional* into a *Stream. An argument for adding mapOrElseGet (notice that the primitive variants return U) is that other functionality can be composed from it.

And later:

I think it’s fine to to pollute OptionalInt etc with Optional but i want to avoid it for the other direction.

In general I think it's reasonable. The purpose of primitive streams is to improve the performance when you process many primitive values. However for Optional the performance gain of using the primitive value is quite marginal if any (there are much bigger chances compared to streams that extra boxing will by optimized out by JIT-compiler). Also even though project Valhalla will not appear in Java-9, it's gradually moving forward and it's possible that in Java-10 we will finally see generics-over-primitives, so these primitive optionals will become completely unnecessary. In this context adding more interoperability between Object Optional and primitive OptionalInt seems unnecessary.

like image 160
Tagir Valeev Avatar answered Sep 18 '22 21:09

Tagir Valeev


It makes sense to have specializations in the Stream API as a stream may represent bulk operations processing millions of elements, thus the performance impact can be dramatic. But as far as I know, even this decision wasn’t without a controversy.

For an Optional, carrying at most one element, the performance impact is not justifying additional APIs (if there ever is an impact). It’s not quite clear whether OptionalInt, etc. are really necessary at all.

Regarding the convenience, I can’t get your point. The following works:

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

your proposal is to add another API which allows to rewrite the above statement as

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

I don’t see how this raises the convenience…

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

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

which raises this kind of “convenience” even more…

like image 29
Holger Avatar answered Sep 20 '22 21:09

Holger