44import java .util .NoSuchElementException ;
55import java .util .Objects ;
66import java .util .function .Consumer ;
7+ import java .util .function .Function ;
8+ import java .util .function .Predicate ;
9+ import java .util .function .Supplier ;
10+ import java .util .stream .Stream ;
711
812public class JsonNullable <T > implements Serializable {
913
@@ -66,15 +70,86 @@ public T orElse(T other) {
6670 return this .isPresent ? this .value : other ;
6771 }
6872
73+ /**
74+ * If a value is present, returns the value, otherwise returns the result
75+ * produced by the supplying function.
76+ *
77+ * @param supplier the supplying function that produces a value to be returned
78+ * @return the value, if present, otherwise the result produced by the supplying function
79+ * @throws NullPointerException if no value is present and the supplying function is null
80+ *
81+ * @since 0.2.8
82+ */
83+ public T orElseGet (Supplier <? extends T > supplier ) {
84+ return this .isPresent ? this .value : supplier .get ();
85+ }
86+
87+ /**
88+ * If a value is present, returns the value, otherwise throws
89+ * NoSuchElementException.
90+ *
91+ * @return the value of this JsonNullable
92+ * @throws NoSuchElementException if no value if present
93+ *
94+ * @since 0.2.8
95+ */
96+ public T orElseThrow () {
97+ if (!isPresent ) {
98+ throw new NoSuchElementException ("Value is undefined" );
99+ }
100+ return value ;
101+ }
102+
103+ /**
104+ * If a value is present, returns the value, otherwise throws an exception
105+ * produced by the exception supplying function.
106+ *
107+ * @param <X> type of the exception to be thrown
108+ * @param supplier the supplying function that produces an exception to be
109+ * thrown
110+ * @return the value, if present
111+ * @throws X if no value is present
112+ * @throws NullPointerException if no value is present and the exception
113+ * supplying function is {@code null}
114+ *
115+ * @since 0.2.8
116+ */
117+ public <X extends Throwable > T orElseThrow (Supplier <? extends X > supplier )
118+ throws X
119+ {
120+ if ( this .isPresent ) {
121+ return this .value ;
122+ }
123+ throw supplier .get ();
124+ }
125+
126+ /**
127+ * If a value is present, returns true, otherwise false.
128+ *
129+ * @return true if a value is present, otherwise false
130+ */
69131 public boolean isPresent () {
70132 return isPresent ;
71133 }
72134
135+ /**
136+ * If a value is not present, returns true, otherwise false.
137+ *
138+ * @return true if a value is not present, otherwise false
139+ *
140+ * @since 0.2.8
141+ */
142+ public boolean isUndefined () {
143+ return !isPresent ;
144+ }
145+
73146 /**
74147 * If a value is present, performs the given action with the value,
75148 * otherwise does nothing.
76149 *
77150 * @param action the action to be performed, if a value is present
151+ * @throws NullPointerException if a value is present and the given action
152+ * is null
78153 */
79154 public void ifPresent (
80155 Consumer <? super T > action ) {
@@ -84,6 +159,153 @@ public void ifPresent(
84159 }
85160 }
86161
162+ /**
163+ * If a value is present, performs the given action with the value,
164+ * otherwise performs the given empty-based action.
165+ *
166+ * @param action the action to be performed, if a value is present
167+ * @param undefinedAction the empty-based action to be performed, if no
168+ * value is present
169+ * @throws NullPointerException if a value is present and the given action
170+ * is null, or no value is present and the given empty-based action
171+ * is null
172+ *
173+ * @since 0.2.8
174+ */
175+ public void ifPresentOrElse ( Consumer <? super T > action , Runnable undefinedAction ) {
176+ if (this .isPresent ) {
177+ action .accept (value );
178+ }
179+ else {
180+ undefinedAction .run ();
181+ }
182+ }
183+
184+ /**
185+ * If a value is present, and the value matches the given predicate, returns
186+ * a JsonNullable describing the value, otherwise returns an undefined
187+ * JsonNullable.
188+ *
189+ * @param predicate the predicate to apply to a value, if present
190+ * @return a JsonNullable describing the value of this JsonNullable,
191+ * if a value is present and the value matches the given predicate,
192+ * otherwise an undefined JsonNullable
193+ * @throws NullPointerException if the predicate is null
194+ *
195+ * @since 0.2.8
196+ */
197+ public JsonNullable <T > filter ( Predicate <T > predicate ) {
198+ if (predicate == null ) {
199+ throw new NullPointerException ("filter predicate is null" );
200+ }
201+ if (this .isPresent && predicate .test (value )) {
202+ return this ;
203+ }
204+ else {
205+ return undefined ();
206+ }
207+ }
208+
209+ /**
210+ * If a value is present, returns a JsonNullable describing the result of
211+ * applying the given mapping function to the value, otherwise returns an
212+ * undeined JsonNullable.
213+ *
214+ * @param <U> the type of the value returned from the mapping function
215+ * @param mapper the mapping function to apply to a value, if present
216+ * @return a JsonNullable describing the result of applying a mapping
217+ * function to the value of this JsonNullable, if a value is
218+ * present, otherwise an undefined JsonNullable
219+ * @throws NullPointerException if the mapping function is null
220+ *
221+ * @since 0.2.8
222+ */
223+ public <U > JsonNullable <U > map ( Function <T , U > mapper ) {
224+ if (mapper == null ) {
225+ throw new NullPointerException ("mapping function is null" );
226+ }
227+ if (this .isPresent ) {
228+ return new JsonNullable <U >(mapper .apply (value ), true );
229+ }
230+ return undefined ();
231+ }
232+
233+ /**
234+ * If a value is present, returns the result of applying the given
235+ * JsonNullable-bearing mapping function to the value, otherwise returns an
236+ * undefined JsonNullable.
237+ *
238+ * @param <U> the type of value of the JsonNullable returned by the mapping
239+ * function
240+ * @param mapper the mapping function to apply to a value, if present
241+ * @return the result of applying a JsonNullable-bearing mapping function to
242+ * the value of this JsonNullable, if a value is present, otherwise
243+ * an undefined JsonNullable
244+ * @throws NullPointerException if the mapping function is null or returns a
245+ * null result
246+ *
247+ * @since 0.2.8
248+ */
249+ @ SuppressWarnings ("unchecked" )
250+ public <U > JsonNullable <U > flatMap ( Function <? super T , ? extends JsonNullable <? extends U >> mapper ) {
251+ if (mapper == null ) {
252+ throw new NullPointerException ("mapping function is null" );
253+ }
254+ if (!this .isPresent ) {
255+ return undefined ();
256+ }
257+
258+ JsonNullable <U > mapped = (JsonNullable <U >)mapper .apply (value );
259+ if (mapped == null ) {
260+ throw new NullPointerException ("mapped value is null" );
261+ }
262+ return mapped ;
263+ }
264+
265+ /**
266+ * If a value is present, returns a JsonNullable describing the value,
267+ * otherwise returns a JsonNullable produced by the supplying function.
268+ *
269+ * @param supplier the supplying function that produces a JsonNullable to be
270+ * returned
271+ * @return returns a JsonNullable describing the value of this JsonNullable,
272+ * if a value is present, otherwise a JsonNullable produced by the
273+ * supplying function.
274+ * @throws NullPointerException if the supplying function is null or
275+ * produces a null result
276+ *
277+ * @since 0.2.8
278+ */
279+ @ SuppressWarnings ("unchecked" )
280+ public JsonNullable <T > or ( Supplier <? extends JsonNullable <? extends T >> supplier ) {
281+ if ( supplier == null ) {
282+ throw new NullPointerException ("or supplier is null" );
283+ }
284+ if (this .isPresent ) {
285+ return this ;
286+ }
287+ JsonNullable <T > supplied = (JsonNullable <T >)supplier .get ();
288+ if (supplied == null ) {
289+ throw new NullPointerException ("supplied value is null" );
290+ }
291+ return supplied ;
292+ }
293+
294+ /**
295+ * If a value is present, returns a sequential Stream containing only that
296+ * value, otherwise returns an empty Stream.
297+ *
298+ * @return the JsonNullable value as a Stream
299+ *
300+ * @since 0.2.8
301+ */
302+ public Stream <T > stream () {
303+ if (this .isPresent ) {
304+ return Stream .of (value );
305+ }
306+ return Stream .empty ();
307+ }
308+
87309 @ Override
88310 public boolean equals (Object obj ) {
89311 if (this == obj ) {
0 commit comments