Like map() , flatMap() unpacks the contents of non- empty Optionals to hand to the mapping function. The only difference is that flatMap() doesn’t wrap the result in an Optional, because the mapping function has already done that.
For example:
// streams/OptionalFlatMap.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
class OptionalFlatMap {
static String[] elements = {"12", "", "23", "45"};
static Stream<String> testStream() {
return Arrays.stream(elements);
}
static void test(String descr, Function<String, Optional<String>> func) {
System.out.println(" ---( " + descr + " )---");
for (int i = 0; i <= elements.length; i++) {
System.out.println(testStream().skip(i).findFirst().flatMap(func));
}
}
public static void main(String[] args) {
test("Add brackets", s -> Optional.of("[" + s + "]"));
test(
"Increment",
s -> {
try {
return Optional.of(Integer.parseInt(s) + 1 + "");
} catch (NumberFormatException e) {
return Optional.of(s);
}
});
test("Replace", s -> Optional.of(s.replace("2", "9"))); // note this output.
test("Take last digit", s -> Optional.of(s.length() > 0 ? s.charAt(s.length() - 1) + "" : s));
}
}
/* Output:
---( Add brackets )---
Optional[[12]]
Optional[[]]
Optional[[23]]
Optional[[45]]
Optional.empty
---( Increment )---
Optional[13]
Optional[]
Optional[24]
Optional[46]
Optional.empty
---( Replace )---
Optional[19]
Optional[]
Optional[93]
Optional[45]
Optional.empty
---( Take last digit )---
Optional[2]
Optional[]
Optional[3]
Optional[5]
Optional.empty
*/
Optional<T> findFirst()
Returns an Optional
describing the first element of this stream, or an empty Optional
if the stream is empty. If the stream has no encounter order, then any element may be returned.
This is a short-circuiting terminal operation.
Returns:
an Optional
describing the first element of this stream, or an empty Optional
if the stream is empty
Throws:
NullPointerException
- if the element selected is null
public <U> Optional<U> flatMap(Function<? super T,Optional<U>> mapper)
If a value is present, apply the provided Optional
-bearing mapping function to it, return that result, otherwise return an empty Optional
. This method is similar to map(Function)
, but the provided mapper is one whose result is already an Optional
, and if invoked, flatMap
does not wrap it with an additional Optional
.
Type Parameters:
U
- The type parameter to the Optional
returned by
Parameters:
mapper
- a mapping function to apply to the value, if present the mapping function
Returns:
the result of applying an Optional
-bearing mapping function to the value of this Optional
, if a value is present, otherwise an empty Optional
Throws:
NullPointerException
- if the mapping function is null or returns a null result
Optional.flatMap() is designed for functions already producing Optionals by themselves.
references:
1. On Java 8 - Bruce Eckel
2. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/streams/OptionalFlatMap.java
3. https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#findFirst--
5. http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/util/Optional.java