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,84 @@ 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+ *
113+ * @since 0.2.8
114+ */
115+ public <X extends Throwable > T orElseThrow (Supplier <? extends X > supplier )
116+ throws X
117+ {
118+ if ( this .isPresent ) {
119+ return this .value ;
120+ }
121+ throw supplier .get ();
122+ }
123+
124+ /**
125+ * If a value is present, returns true, otherwise false.
126+ *
127+ * @return true if a value is present, otherwise false
128+ */
69129 public boolean isPresent () {
70130 return isPresent ;
71131 }
72132
133+ /**
134+ * If a value is not present, returns true, otherwise false.
135+ *
136+ * @return true if a value is not present, otherwise false
137+ *
138+ * @since 0.2.8
139+ */
140+ public boolean isUndefined () {
141+ return !isPresent ;
142+ }
143+
73144 /**
74145 * If a value is present, performs the given action with the value,
75146 * otherwise does nothing.
76147 *
77148 * @param action the action to be performed, if a value is present
149+ * @throws NullPointerException if a value is present and the given action
150+ * is null
78151 */
79152 public void ifPresent (
80153 Consumer <? super T > action ) {
@@ -84,6 +157,141 @@ public void ifPresent(
84157 }
85158 }
86159
160+ /**
161+ * If a value is present, performs the given action with the value,
162+ * otherwise performs the given empty-based action.
163+ *
164+ * @param action the action to be performed, if a value is present
165+ * @param undefinedAction the empty-based action to be performed, if no
166+ * value is present
167+ * @throws NullPointerException if a value is present and the given action
168+ * is null, or no value is present and the given empty-based action
169+ * is null
170+ *
171+ * @since 0.2.8
172+ */
173+ public void ifPresentOrElse ( Consumer <? super T > action , Runnable undefinedAction ) {
174+ if (this .isPresent ) {
175+ action .accept (value );
176+ }
177+ else {
178+ undefinedAction .run ();
179+ }
180+ }
181+
182+ /**
183+ * If a value is present, and the value matches the given predicate, returns
184+ * a JsonNullable describing the value, otherwise returns an undefined
185+ * JsonNullable.
186+ *
187+ * @param predicate the predicate to apply to a value, if present
188+ * @return a JsonNullable describing the value of this JsonNullable,
189+ * if a value is present and the value matches the given predicate,
190+ * otherwise an undefined JsonNullable
191+ * @throws NullPointerException if the predicate is null
192+ *
193+ * @since 0.2.8
194+ */
195+ public JsonNullable <T > filter ( Predicate <T > predicate ) {
196+ if (this .isPresent && predicate .test (value )) {
197+ return this ;
198+ }
199+ else {
200+ return undefined ();
201+ }
202+ }
203+
204+ /**
205+ * If a value is present, returns a JsonNullable describing the result of
206+ * applying the given mapping function to the value, otherwise returns an
207+ * undeined JsonNullable.
208+ *
209+ * @param <U> the type of the value returned from the mapping function
210+ * @param mapper the mapping function to apply to a value, if present
211+ * @return a JsonNullable describing the result of applying a mapping
212+ * function to the value of this JsonNullable, if a value is
213+ * present, otherwise an undefined JsonNullable
214+ * @throws NullPointerException if the mapping function is null
215+ *
216+ * @since 0.2.8
217+ */
218+ public <U > JsonNullable <U > map ( Function <T , U > mapper ) {
219+ if (this .isPresent ) {
220+ return new JsonNullable <U >(mapper .apply (value ), true );
221+ }
222+ return undefined ();
223+ }
224+
225+ /**
226+ * If a value is present, returns the result of applying the given
227+ * JsonNullable-bearing mapping function to the value, otherwise returns an
228+ * undefined JsonNullable.
229+ *
230+ * @param <U> the type of value of the JsonNullable returned by the mapping
231+ * function
232+ * @param mapper the mapping function to apply to a value, if present
233+ * @return the result of applying a JsonNullable-bearing mapping function to
234+ * the value of this JsonNullable, if a value is present, otherwise
235+ * an undefined JsonNullable
236+ * @throws NullPointerException if the mapping function is null or returns a
237+ * null result
238+ *
239+ * @since 0.2.8
240+ */
241+ @ SuppressWarnings ("unchecked" )
242+ public <U > JsonNullable <U > flatMap ( Function <? super T , ? extends JsonNullable <? extends U >> mapper ) {
243+ if (!this .isPresent ) {
244+ return (JsonNullable <U >)this ;
245+ }
246+
247+ JsonNullable <U > mapped = (JsonNullable <U >)mapper .apply (value );
248+ if (mapped == null ) {
249+ throw new NullPointerException ("The mapped value is null" );
250+ }
251+ return mapped ;
252+ }
253+
254+ /**
255+ * If a value is present, returns a JsonNullable describing the value,
256+ * otherwise returns a JsonNullable produced by the supplying function.
257+ *
258+ * @param supplier the supplying function that produces a JsonNullable to be
259+ * returned
260+ * @return returns a JsonNullable describing the value of this JsonNullable,
261+ * if a value is present, otherwise a JsonNullable produced by the
262+ * supplying function.
263+ * @throws NullPointerException if the supplying function is null or
264+ * produces a null result
265+ *
266+ * @since 0.2.8
267+ */
268+ @ SuppressWarnings ("unchecked" )
269+ public JsonNullable <T > or ( Supplier <? extends JsonNullable <? extends T >> supplier ) {
270+ if (this .isPresent ) {
271+ return this ;
272+ }
273+ JsonNullable <T > supplied = (JsonNullable <T >)supplier .get ();
274+ if (supplied == null ) {
275+ throw new NullPointerException ("The supplied value is null" );
276+ }
277+ return supplied ;
278+ }
279+
280+ /**
281+ * If a value is present, returns a sequential Stream containing only that
282+ * value, otherwise returns an empty Stream.
283+ *
284+ * @return the JsonNullable value as a Stream
285+ *
286+ * @since 0.2.8
287+ */
288+ public Stream <T > stream () {
289+ if (this .isPresent ) {
290+ return Stream .of (value );
291+ }
292+ return Stream .empty ();
293+ }
294+
87295 @ Override
88296 public boolean equals (Object obj ) {
89297 if (this == obj ) {
0 commit comments