8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package java.util;
26
27 import java.util.function.Consumer;
28 import java.util.function.Supplier;
29
30 /**
31 * A container object which may or may not contain a non-null value.
32 * If a value is present, {@code isPresent()} will return {@code true} and
33 * {@code get()} will return the value.
34 *
35 * <p>Additional methods that depend on the presence or absence of a contained
36 * value are provided, such as {@link #orElse(java.lang.Object) orElse()}
37 * (return a default value if value not present) and
38 * {@link #ifPresent(java.util.function.Consumer) ifPresent()} (execute a block
39 * of code if the value is present).
40 *
41 * @since 1.8
42 */
43 public final class Optional<T> {
44 /**
45 * Common instance for {@code empty()}.
46 */
47 private static final Optional<?> EMPTY = new Optional<>();
48
49 /**
50 * If non-null, the value; if null, indicates no value is present
51 */
52 private final T value;
53
54 /**
55 * Construct an empty instance.
56 *
57 * @implNote Generally only one empty instance, {@link Optional#EMPTY},
58 * should exist per VM.
59 */
60 private Optional() {
61 this.value = null;
62 }
63
64 /**
65 * Returns an empty {@code Optional} instance. No value is present for this
66 * Optional.
67 *
68 * @apiNote Though it may be tempting to do so, avoid testing if an object
69 * is empty by comparing with {@code ==} against instances returned by
70 * {@code Option.empty()}. There is no guarantee that it is a singleton.
71 * Instead, use {@link #isPresent()}.
72 *
73 * @param <T> Type of the non-existent value
74 * @return an empty {@code Optional}
75 */
76 public static<T> Optional<T> empty() {
77 @SuppressWarnings("unchecked")
78 Optional<T> t = (Optional<T>) EMPTY;
79 return t;
80 }
81
82 /**
83 * Construct an instance with the value present.
84 *
85 * @param value the non-null value to be present
86 */
87 private Optional(T value) {
88 this.value = Objects.requireNonNull(value);
89 }
90
91 /**
92 * Return an {@code Optional} with the specified present value.
93 *
94 * @param value the value to be present, which must be non-null
95 * @return an {@code Optional} with the value present
96 */
97 public static <T> Optional<T> of(T value) {
98 return new Optional<>(value);
99 }
100
101 /**
102 * If a value is present in this {@code Optional}, returns the value,
103 * otherwise throws {@code NoSuchElementException}.
104 *
105 * @return the non-null value held by this {@code Optional}
106 * @throws NoSuchElementException if there is no value present
107 *
108 * @see Optional#isPresent()
109 */
110 public T get() {
111 if (value == null) {
112 throw new NoSuchElementException("No value present");
113 }
114 return value;
115 }
116
117 /**
118 * Return {@code true} if there is a value present, otherwise {@code false}.
119 *
120 * @return {@code true} if there is a value present, otherwise {@code false}
121 */
122 public boolean isPresent() {
123 return value != null;
124 }
125
126 /**
127 * Have the specified consumer accept the value if a value is present,
128 * otherwise do nothing.
129 *
130 * @param consumer block to be executed if a value is present
131 * @throws NullPointerException if value is present and {@code consumer} is
132 * null
133 */
134 public void ifPresent(Consumer<? super T> consumer) {
135 if (value != null)
136 consumer.accept(value);
137 }
138
139 /**
140 * Return the value if present, otherwise return {@code other}.
141 *
142 * @param other the value to be returned if there is no value present, may
143 * be null
144 * @return the value, if present, otherwise {@code other}
145 */
146 public T orElse(T other) {
147 return value != null ? value : other;
148 }
149
150 /**
151 * Return the value if present, otherwise invoke {@code other} and return
152 * the result of that invocation.
153 *
154 * @param other a {@code Supplier} whose result is returned if no value
155 * is present
156 * @return the value if present otherwise the result of {@code other.get()}
|
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package java.util;
26
27 import java.util.function.Consumer;
28 import java.util.function.Function;
29 import java.util.function.Predicate;
30 import java.util.function.Supplier;
31
32 /**
33 * A container object which may or may not contain a non-null value.
34 * If a value is present, {@code isPresent()} will return {@code true} and
35 * {@code get()} will return the value.
36 *
37 * <p>Additional methods that depend on the presence or absence of a contained
38 * value are provided, such as {@link #orElse(java.lang.Object) orElse()}
39 * (return a default value if value not present) and
40 * {@link #ifPresent(java.util.function.Consumer) ifPresent()} (execute a block
41 * of code if the value is present).
42 *
43 * @since 1.8
44 */
45 public final class Optional<T> {
46 /**
47 * Common instance for {@code empty()}.
48 */
49 private static final Optional<?> EMPTY = new Optional<>();
50
51 /**
52 * If non-null, the value; if null, indicates no value is present
53 */
54 private final T value;
55
56 /**
57 * Constructs an empty instance.
58 *
59 * @implNote Generally only one empty instance, {@link Optional#EMPTY},
60 * should exist per VM.
61 */
62 private Optional() {
63 this.value = null;
64 }
65
66 /**
67 * Returns an empty {@code Optional} instance. No value is present for this
68 * Optional.
69 *
70 * @apiNote Though it may be tempting to do so, avoid testing if an object
71 * is empty by comparing with {@code ==} against instances returned by
72 * {@code Option.empty()}. There is no guarantee that it is a singleton.
73 * Instead, use {@link #isPresent()}.
74 *
75 * @param <T> Type of the non-existent value
76 * @return an empty {@code Optional}
77 */
78 public static<T> Optional<T> empty() {
79 @SuppressWarnings("unchecked")
80 Optional<T> t = (Optional<T>) EMPTY;
81 return t;
82 }
83
84 /**
85 * Constructs an instance with the value present.
86 *
87 * @param value the non-null value to be present
88 */
89 private Optional(T value) {
90 this.value = Objects.requireNonNull(value);
91 }
92
93 /**
94 * Returns an {@code Optional} with the specified present non-null value.
95 *
96 * @param value the value to be present, which must be non-null
97 * @return an {@code Optional} with the value present
98 */
99 public static <T> Optional<T> of(T value) {
100 return new Optional<>(value);
101 }
102
103 /**
104 * Returns an {@code Optional} describing the specified value, if non-null,
105 * otherwise returns an empty {@code Optional}.
106 *
107 * @param value the possibly-null value to describe
108 * @return an {@code Optional} with a present value if the specified value
109 * is non-null, otherwise an empty {@code Optional}
110 */
111 public static <T> Optional<T> ofNullable(T value) {
112 return value == null ? empty() : of(value);
113 }
114
115 /**
116 * If a value is present in this {@code Optional}, returns the value,
117 * otherwise throws {@code NoSuchElementException}.
118 *
119 * @return the non-null value held by this {@code Optional}
120 * @throws NoSuchElementException if there is no value present
121 *
122 * @see Optional#isPresent()
123 */
124 public T get() {
125 if (value == null) {
126 throw new NoSuchElementException("No value present");
127 }
128 return value;
129 }
130
131 /**
132 * Return {@code true} if there is a value present, otherwise {@code false}.
133 *
134 * @return {@code true} if there is a value present, otherwise {@code false}
135 */
136 public boolean isPresent() {
137 return value != null;
138 }
139
140 /**
141 * If a value is present, invoke the specified consumer with the value,
142 * otherwise do nothing.
143 *
144 * @param consumer block to be executed if a value is present
145 * @throws NullPointerException if value is present and {@code consumer} is
146 * null
147 */
148 public void ifPresent(Consumer<? super T> consumer) {
149 if (value != null)
150 consumer.accept(value);
151 }
152
153 /**
154 * If a value is present, and the value matches the given predicate,
155 * return an {@code Optional} describing the value, otherwise return an
156 * empty {@code Optional}.
157 *
158 * @param predicate a predicate to apply to the value, if present
159 * @return an {@code Optional} describing the value of this {@code Optional}
160 * if a value is present and the value matches the given predicate,
161 * otherwise an empty {@code Optional}
162 * @throws NullPointerException if the predicate is null
163 */
164 public Optional<T> filter(Predicate<? super T> predicate) {
165 Objects.requireNonNull(predicate);
166 if (!isPresent())
167 return this;
168 else
169 return predicate.test(value) ? this : empty();
170 }
171
172 /**
173 * If a value is present, apply the provided mapping function to it,
174 * and if the result is non-null, return an {@code Optional} describing the
175 * result. Otherwise return an empty {@code Optional}.
176 *
177 * @apiNote This method supports post-processing on optional values, without
178 * the need to explicitly check for a return status. For example, the
179 * following code traverses a stream of file names, selects one that has
180 * not yet been processed, and then opens that file, returning an
181 * {@code Optional<FileInputStream>}:
182 *
183 * <pre>{@code
184 * Optional<FileInputStream> fis =
185 * names.stream().filter(name -> !isProcessedYet(name))
186 * .findFirst()
187 * .map(name -> new FileInputStream(name));
188 * }</pre>
189 *
190 * Here, {@code findFirst} returns an {@code Optional<String>}, and then
191 * {@code map} returns an {@code Optional<FileInputStream>} for the desired
192 * file if one exists.
193 *
194 * @param <U> The type of the result of the mapping function
195 * @param mapper a mapping function to apply to the value, if present
196 * @return an {@code Optional} describing the result of applying a mapping
197 * function to the value of this {@code Optional}, if a value is present,
198 * otherwise an empty {@code Optional}
199 * @throws NullPointerException if the mapping function is null
200 */
201 public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
202 Objects.requireNonNull(mapper);
203 if (!isPresent())
204 return empty();
205 else {
206 return Optional.ofNullable(mapper.apply(value));
207 }
208 }
209
210 /**
211 * If a value is present, apply the provided {@code Optional}-bearing
212 * mapping function to it, return that result, otherwise return an empty
213 * {@code Optional}. This method is similar to {@link #map(Function)},
214 * but the provided mapper is one whose result is already an {@code Optional},
215 * and if invoked, {@code flatMap} does not wrap it with an additional
216 * {@code Optional}.
217 *
218 * @param <U> The type parameter to the {@code Optional} returned by
219 * @param mapper a mapping function to apply to the value, if present
220 * the mapping function
221 * @return the result of applying an {@code Optional}-bearing mapping
222 * function to the value of this {@code Optional}, if a value is present,
223 * otherwise an empty {@code Optional}
224 * @throws NullPointerException if the mapping function is null or returns
225 * a null result
226 */
227 public<U> Optional<U> flatMap(Function<? super T, ? extends Optional<U>> mapper) {
228 Objects.requireNonNull(mapper);
229 if (!isPresent())
230 return empty();
231 else {
232 return Objects.requireNonNull(mapper.apply(value));
233 }
234 }
235
236 /**
237 * Return the value if present, otherwise return {@code other}.
238 *
239 * @param other the value to be returned if there is no value present, may
240 * be null
241 * @return the value, if present, otherwise {@code other}
242 */
243 public T orElse(T other) {
244 return value != null ? value : other;
245 }
246
247 /**
248 * Return the value if present, otherwise invoke {@code other} and return
249 * the result of that invocation.
250 *
251 * @param other a {@code Supplier} whose result is returned if no value
252 * is present
253 * @return the value if present otherwise the result of {@code other.get()}
|