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

no.finn.lambdacompanion.StreamableOptional Maven / Gradle / Ivy

There is a newer version: 0.27
Show newest version
package no.finn.lambdacompanion;

import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Stream;

/**
 * Wrapper around an usual {@link java.util.Optional} that provides the very missed {@link #stream()} method useful for
 * flatMapping a {@link java.util.stream.Stream} of {@link java.util.Optional} (i.e. only keep present values).
 * 

* example: the good *

 * {@code
 * collection.stream().flatMap(item -> StreamableOptional.ofNullable(item.getNullableProperty()).stream())
 * }
 * 
* would replace the bad: *
 * {@code
 * collection.stream().map(item -> Optional.ofNullable(item.getNullableProperty())).filter(Optional::isPresent).map(Optional::get)
 * }
 * 
* or the ugly: *
 * {@code
 * collection.stream().flatMap(item -> Optional.ofNullable(item.getNullableProperty()).map(Stream::of).orElseGet(Stream::empty))
 * }
 * 
*/ public class StreamableOptional { private static final StreamableOptional EMPTY = new StreamableOptional(Optional.empty()); private final Optional optional; private StreamableOptional(final Optional optional) { this.optional = optional; } /** * @see java.util.Optional#ifPresent(java.util.function.Consumer) * @param consumer consumer */ public void ifPresent(Consumer consumer) { optional.ifPresent(consumer); } /** * @see java.util.Optional#filter(java.util.function.Predicate) * @param predicate predicate * @return StreamableOptional */ public StreamableOptional filter(Predicate predicate) { return optional.filter(predicate).map(present -> this).orElse(empty()); } /** * @see java.util.Optional#map(java.util.function.Function) * @param u * @param mapper mapper * @return U */ public StreamableOptional map(Function mapper) { return optional.map(mapper).map(StreamableOptional::of).orElse(empty()); } /** * @see java.util.Optional#flatMap(java.util.function.Function) * @param u * @param mapper mapper * @return U */ public StreamableOptional flatMap(Function> mapper) { return optional.map(present -> Objects.requireNonNull(mapper.apply(present))).orElse(empty()); } /** * @see java.util.Optional#orElse(Object) * @param other other * @return T t */ public T orElse(T other) { return optional.orElse(other); } /** * @see java.util.Optional#orElseGet(java.util.function.Supplier) * @param other other * @return T t */ public T orElseGet(Supplier other) { return optional.orElseGet(other); } /** * @see java.util.Optional#orElseThrow(java.util.function.Supplier) * @param exceptionSupplier exceptionSupplier * @param x * @throws X x * @return T t */ public T orElseThrow(Supplier exceptionSupplier) throws X { return optional.orElseThrow(exceptionSupplier); } /** * Turns this optional into a {@link java.util.stream.Stream} * @return a {@link java.util.stream.Stream} of the one value contained within this optional if it is present, an empty stream else */ public Stream stream() { return optional.map(Stream::of).orElseGet(Stream::empty); } /** * @return the {@link java.util.Optional} within */ public Optional toOptional() { return optional; } /** * @see java.util.Optional#of(Object) * @param t * @param value value * @return T t */ public static StreamableOptional of(final T value) { return ofOptional(Optional.of(value)); } /** * @see java.util.Optional#ofNullable(Object) * @param t * @param value value * @return T t */ public static StreamableOptional ofNullable(final T value) { return ofOptional(Optional.ofNullable(value)); } /** * Builds a StreamableOptional around the given {@link java.util.Optional} * * @param t * @param optional a regular {@link java.util.Optional} * @return a StreamableOptional */ public static StreamableOptional ofOptional(final Optional optional) { Objects.requireNonNull(optional); if (!optional.isPresent()) { return empty(); } return new StreamableOptional<>(optional); } /** * @see java.util.Optional#empty() * @param t * @return T t */ public static StreamableOptional empty() { return (StreamableOptional) EMPTY; } @Override public boolean equals(final Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } final StreamableOptional that = (StreamableOptional) o; if (!optional.equals(that.optional)) { return false; } return true; } @Override public int hashCode() { return optional.hashCode(); } }