All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javascalautils.Option Maven / Gradle / Ivy

There is a newer version: 1.11.2
Show newest version
/**
 * Copyright 2015 Peter Nerg
 *
 * 

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of the License at * *

http://www.apache.org/licenses/LICENSE-2.0 * *

Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ package javascalautils; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Optional; import java.util.function.Predicate; import java.util.function.Supplier; import java.util.stream.Stream; /** * Represents optional values.
* Instances of Option are either an instance of {@link Some} or {@link None}.
* {@link Some} holds a non-null value whilst {@link None} holds no value.
* The primary use case is to replace ugly null-checks.
* Consider the method:
* *

* *
 * SomeData getDataIfExists(SomeInput input) {
 *   if(haveData(input) {
 *      return getSomeDataFromInternalStorage();
 *   }
 *   return null;
 * }
 * 
* *
* * The above method causes the user to do null-checks in case the method returned a proper value or * not.
* A neater way would be: * *
* *
 * Option<SomeData> getDataIfExists(SomeInput input) {
 *   if(haveData(input) {
 *      return new Some<>(getSomeDataFromInternalStorage());
 *   }
 *   return Option.None();
 * }
 * 
* *
* * Another example is the usage of {@link java.util.Map Maps}.
* Performing a get on a Map will either yield the value of the key or null if no such * key existed.
* Consider the Map:
* *
* * Map<String, SomeData> map = .... * *
* *
* To avoid null checks one could do like so:
* *
* * Option<SomeData> option = Option.apply(map.get("someKey")); * *
* * Now you have a guaranteed non-null value with which you can work with without performing constant * null-checks.
* Statically importing methods from the companion class ({@link OptionCompanion}) to Option one can * get that Scala feel of declaration.
* *
* *
 * import static javascalautils.OptionCompanion.Option;
 *
 * Option<String> option = Option(map.get("someKey"));
 * 
* *
* * @author Peter Nerg * @since 1.0 * @param The type of the value represented by this instance */ public interface Option extends Iterable { /** * This is a singleton {@link None} since it anyways cannot represent a state.
* Can also be accessed using {@link #empty()} */ @SuppressWarnings("rawtypes") None DEFAULT_NONE = new None(); /** * Creates an instance of Option.
* If a null value is provided then {@link None} is returned, else {@link Some} * containing the provided value. * * @param The type for the value this Option represents * @param value The value this Option shall represent * @return The Option representing the provided value * @since 1.0 */ static Option apply(T value) { return value != null ? new Some<>(value) : None(); } /** * Returns an empty Option.
* In practice this returns a {@link #DEFAULT_NONE singleton} as it anyways cannot represent a * value/state. * * @param The type for the value this Option represents * @return The default {@link None} instance * @since 1.0 */ static Option empty() { return None(); } /** * Returns an empty Option.
* This is the same as {@link #empty()} but with the difference it provides a more Scala like * feeling if the method is statically imported.
* One can use None() as if it was a apply method on a companion object in Scala. *
* E.g. * *
* *
   * import static javascalautils.Option.None;
   *
   * Option<String> opt = None();
   * 
* *
* * @param The type for the value this Option represents * @return The default {@link None} instance * @since 1.2 */ @SuppressWarnings("unchecked") static Option None() { return DEFAULT_NONE; } /** * Returns true if this is a {@link Some} containing the provided object, else * false. * * @param other The other object to compare to * @return If this {@link Some} contains the provided object * @since 1.0 */ default boolean contains(final T other) { return exists(value -> value.equals(other)); } /** * Returns the count which means 1 for nonempty Option's and 0 for * empty. * * @return The count * @since 1.0 */ default int count() { // map will either return Some(1) or None upon which the else(0) will be returned. return map(value -> 1).getOrElse(() -> 0); } /** * Returns true if this option is nonempty and the predicate p returns true * when applied to this Option's value. * * @param predicate The predicate * @return If the predicate matches * @since 1.0 */ boolean exists(Predicate predicate); /** * Returns this Option if it is nonempty and applying the predicate p to this Option's value * returns true. * * @param predicate The predicate * @return The Option representing the match * @since 1.0 */ default Option filter(Predicate predicate) { return exists(predicate) ? this : None(); } /** * Returns this Option if it is nonempty and applying the predicate p to this Option's value * returns false. * * @param predicate The predicate * @return The Option representing the match * @since 1.0 */ default Option filterNot(final Predicate predicate) { // filter not is in practice just negating the result of the provided predicate return filter(value -> !predicate.test(value)); } /** * Returns true if the Option is nonempty and the predicate holds true, * else false.
* As an {@link Option} is a zero-or-one sized collection this is in an essence exactly the same * as {@link #exists(Predicate)}. * * @param predicate The predicate * @return If the predicate matches * @since 1.0 */ default boolean forall(Predicate predicate) { return exists(predicate); } /** * Returns this Option's value if such exists, else {@link NoSuchElementException} is raised. * * @return The value of the Option * @since 1.0 */ T get(); /** * Returns this Option's value if such exists, else the value provided by the supplier. * * @param supplier The supplier to use in case this is a {@link None} * @return The value of the Option or the value provided by the supplier * @since 1.0 */ T getOrElse(Supplier supplier); /** * Returns true if the option is an instance of {@link Some}, false * otherwise. * * @return true this Option is a {@link Some}, else false * @since 1.0 */ default boolean isDefined() { return exists(t -> true); } /** * Returns true if the option is an instance of {@link None}, false * otherwise * * @return true this Option is a {@link None}, else false * @since 1.0 */ default boolean isEmpty() { return !isDefined(); } /** * Returns the Option's value in an {@link Iterator} if it is nonempty, or an empty {@link * Iterator} if it is empty. * * @return The iterator for the Option * @since 1.0 */ @Override Iterator iterator(); /** * Returns an Option consisting of the result of applying the given function to the current {@link * Some}.
* Applying map to {@link None} will always yield {@link None}. * * @param The type for the return value from the function * @param function The function to use * @return The Option containing the mapped value * @since 1.0 */ Option map(ThrowableFunction1 function); /** * Returns an Option consisting of the result of applying the given function to the current {@link * Some}.
* Applying map to {@link None} will always yield {@link None}. * * @param The type for the return value from the function * @param function The function to use * @return The Option containing the mapped value * @since 1.2 */ Option flatMap(ThrowableFunction1> function); /** * Returns this Option if it is nonempty, otherwise return the result of provided by the supplier. * * @param supplier The supplier to use in case of {@link None} * @return This Option or the one provided by the supplier * @since 1.0 */ Option orElse(Supplier> supplier); /** * Returns the Option's value if it is nonempty, or null if it is empty. * * @return The value of the Option or null in case of {@link None} * @since 1.0 */ default T orNull() { return getOrElse(() -> null); } /** * Returns the Option's value in a Stream if it is nonempty, or an empty Stream if it is empty. * * @return The stream for the Option * @since 1.0 */ Stream stream(); /** * Returns the value of this {@link Some} as a {@link Left}, or in case of {@link None} a {@link * Right} containing the value from the provided supplier. * * @param The type in case {@link Right} returned * @param right The supplier to use in case this is a {@link None} * @return The {@link Either} instance * @since 1.4 */ Either toLeft(Supplier right); /** * Returns the value of this {@link Some} as a {@link Right}, or in case of {@link None} a {@link * Left} containing the value from the provided supplier. * * @param The type in case {@link Left} returned * @param left The supplier to use in case this is a {@link None} * @return The {@link Either} instance * @since 1.4 */ Either toRight(Supplier left); /** * Converts this {@link Option} to a corresponding {@link Optional}. * * @return The Optional instance * @since 1.0 */ default Optional asOptional() { return Optional.ofNullable(orNull()); } /** * Converts the {@link Optional} to a corresponding {@link Option}. * * @param The type for the value this Option represents * @param optional The Optional to convert * @return The Option for the provided Optional * @since 1.0 */ static Option ofOptional(Optional optional) { return apply(optional.orElse(null)); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy