View Javadoc
1   /*
2      Copyright 2011 Atlassian
3   
4      Licensed under the Apache License, Version 2.0 (the "License");
5      you may not use this file except in compliance with the License.
6      You may obtain a copy of the License at
7   
8          http://www.apache.org/licenses/LICENSE-2.0
9   
10     Unless required by applicable law or agreed to in writing, software
11     distributed under the License is distributed on an "AS IS" BASIS,
12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13     See the License for the specific language governing permissions and
14     limitations under the License.
15   */
16  package io.atlassian.fugue;
17  
18  import java.util.Iterator;
19  import java.util.NoSuchElementException;
20  import java.util.function.Predicate;
21  import java.util.function.Supplier;
22  
23  /**
24   * Implemented by things that may or may not contain a value.
25   * <p>
26   * Note there are some methods suggested by this interface that cannot be
27   * expressed here as the return type cannot be expressed in Java's type system
28   * (due to the lack of higher-kinded types). These are for instance (where M is
29   * the implementing Maybe sub-type):
30   * <ul>
31   * <li>{@literal <B> Maybe<B> map(Function<? super A, B>)}
32   * <li>{@literal <B> Maybe<B> flatMap(Function<? super A, Maybe<B>>}
33   * <li>{@literal Maybe<A> filter(Predicate<? super A>)}
34   * </ul>
35   *
36   * @param <A> the contained type
37   * @since 1.0
38   */
39  @SuppressWarnings("deprecation") public interface Maybe<A> extends Iterable<A>, Effect.Applicant<A> {
40    /**
41     * Get the value if defined. Throw an exception otherwise.
42     *
43     * @return the wrapped value
44     * @throws NoSuchElementException if this is a none
45     */
46    A get();
47  
48    /**
49     * Get the value if defined, otherwise returns {@code other}.
50     *
51     * @param <B> default value type
52     * @param other value to return if this {@link #isEmpty() is empty}
53     * @return wrapped value if this {@link #isDefined() is defined}, otherwise
54     * returns {@code other}
55     */
56    <B extends A> A getOrElse(final B other);
57  
58    /**
59     * Get the value {@link #isDefined() if defined} or call the supplier and
60     * return its value if not. Replaces {@link #getOrElse(Supplier)}.
61     *
62     * Get the value {@link #isDefined() if defined} or call the supplier and
63     * return its value if not.
64     *
65     * @param supplier called if this {@link #isEmpty() is empty}
66     * @return the wrapped value or the value from the {@code Supplier}
67     */
68    A getOr(final Supplier<? extends A> supplier);
69  
70    /**
71     * Get the value {@link #isDefined() if defined} or call the supplier and
72     * return its value if not.
73     *
74     * @param supplier called if this {@link #isEmpty() is empty}
75     * @return the wrapped value or the value from the {@code Supplier}
76     * @deprecated since 3.0 {@link #getOrElse(Supplier)} is being replaced with
77     * {@link #getOr(Supplier)}. In Java 8 type inference cannot disambiguate
78     * between an overloaded method taking a generic A and the same method taking
79     * a {@literal Supplier<A>}.
80     */
81    @Deprecated A getOrElse(final Supplier<? extends A> supplier);
82  
83    /**
84     * Get the value if defined or null if not.
85     * <p>
86     * Although the use of null is discouraged, code written to use these must
87     * often interface with code that expects and returns nulls.
88     *
89     * @return the value or null if not defined
90     */
91    A getOrNull();
92  
93    /**
94     * Get the value or throws an error with the supplied message if not defined.
95     * <p>
96     * Used when absolutely sure this {@link #isDefined() is defined}.
97     *
98     * @param msg the message for the error.
99     * @return the contained value.
100    */
101   A getOrError(Supplier<String> msg);
102 
103   /**
104    * Get the value or throws the supplied throwable if not defined.
105    * <p>
106    * Used when absolutely sure this {@link #isDefined() is defined}.
107    *
108    * @param <X> exception type
109    * @param ifUndefined the supplier of the throwable.
110    * @throws X the throwable the supplier creates if there is no value.
111    * @return the contained value.
112    * @since 2.0
113    */
114   <X extends Throwable> A getOrThrow(Supplier<X> ifUndefined) throws X;
115 
116   /**
117    * If the type contains a value return true.
118    *
119    * @return {@code true} if this holds a value, {@code false} otherwise.
120    */
121   boolean isDefined();
122 
123   /**
124    * If the type does not contain a value return true.
125    *
126    * @return {@code true} if this does not hold a value, {@code false}
127    * otherwise.
128    */
129   boolean isEmpty();
130 
131   /**
132    * Whether this is {@link #isDefined() is defined} <strong>and</strong>
133    * applying the predicate to the contained value returns true.
134    *
135    * @param p the predicate to test, must not be null
136    * @return {@code true} if defined and the predicate returns true for the
137    * contained value, {@code false} otherwise.
138    */
139   boolean exists(final Predicate<? super A> p);
140 
141   /**
142    * Return an iterator for this type. In most cases this takes the form of an
143    * iterator returning zero or one values.
144    *
145    * @return an iterator over the contained value {@link #isDefined() if
146    * defined}, or an empty one otherwise.
147    */
148   Iterator<A> iterator();
149 
150   /**
151    * Returns <code>true</code> {@link #isEmpty() if empty} or the result of the
152    * application of the given function to the value.
153    *
154    * @param p The predicate function to test on the contained value, must not be
155    * null
156    * @return <code>true</code> if no value or returns the result of the
157    * application of the given function to the value.
158    */
159   boolean forall(final Predicate<? super A> p);
160 }