I'm teaching classes on the new Java constructs. I've already introduced my students to Optional<T>
. Imagining that there is a Point.getQuadrant()
which returns an Optional<Quadrant>
(because some points lie in no quadrant at all), we can add the quadrant to a Set<Quadrant>
if the point lies in a positive X quadrant, like this:
Set<Quadrant> quadrants = ...;
Optional<Point> point = ...;
point
.filter(p -> p.getX() > 0)
.flatMap(Point::getQuadrant)
.ifPresent(quadrants::add);
(That's off the top of my head; let me know if I made a mistake.)
My next step was to tell my students, "Wouldn't it be neat if you could do the same internal filtering and decisions using functions, but with multiple objects? Well that's what streams are for!" It seemed the perfect segue. I was almost ready to write out the same form but with a list of points, using streams:
Set<Point> points = ...;
Set<Quadrant> quadrants = points.stream()
.filter(p -> p.getX() > 0)
.flatMap(Point::getQuadrant)
.collect(Collectors.toSet());
But wait! Will Stream.flatMap(Point::getQuadrant)
correctly unravel the Optional<Quadrant>
? It appears not...
I had already read Using Java 8's Optional with Stream::flatMap , but I had thought that what was discussed there was some esoteric side case with no real-life relevance. But now that I'm playing it out, I see that this is directly relevant to most anything we do.
Put simply, if Java now expects us to use Optional<T>
as the new optional-return idiom; and if Java now encourages us to use streams for processing our objects, wouldn't we expect to encounter mapping to an optional value all over the place? Do we really have to jump through series of .filter(Optional::isPresent).map(Optional::get)
hoops as a workaround until Java 9 gets here years from now?
I'm hoping I just misinterpreted the other question, that I'm just misunderstanding something simple, and that someone can set me straight. Surely Java 8 doesn't have this big of a blind spot, does it?