Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package ch.claude_martin.common;
- import java.util.Collection;
- import java.util.Collections;
- import java.util.Optional;
- import java.util.Set;
- import java.util.function.BiConsumer;
- import java.util.function.BinaryOperator;
- import java.util.function.Function;
- import java.util.function.Supplier;
- import java.util.stream.Collector;
- import java.util.stream.Collectors;
- import java.util.stream.Stream;
- import ch.claude_martin.common.ToOptional.Ref;
- /**
- * Collects a single element from a stream into an {@link Optional}. The returned Optional is empty if
- * there is not exactly one element in the stream.
- *
- * <p>
- * This is an alternative to {@link Stream#findAny()} as it checks that there is exactly one element
- * in the stream that can be <i>found</i>. It can also be seen as an alternative to the
- * {@link Collectors}, as this uses an Optional like a {@link Collection}, similar to
- * {@link Collectors#toList()}.
- * </p>
- *
- * <p>
- * Note that this might take a long time for streams with many elements.
- * </p>
- *
- * <pre>
- * Example:
- * List<Integer> list = Arrays.asList(1,2,3,4);
- * Optional<Integer> o = list.stream().filter(i->i==3).collect(ToOptional.get());
- * System.out.println(o); // Optional[3]
- * o = list.stream().filter(i->i>0).collect(ToOptional.get());
- * System.out.println(o); // Optional.empty
- * </pre>
- *
- * @see Collectors
- * @param <T>
- * Type of the expected element.
- */
- public final class ToOptional<T> implements Collector<T, Ref<T>, Optional<T>> {
- private ToOptional() {
- super();
- }
- public final static ToOptional<?> INSTANCE = new ToOptional<>();
- /**
- * Returns an instance of {@link ToOptional}.
- * <p>
- * Note: This always returns the same {@link Collector}.
- */
- @SuppressWarnings("unchecked")
- public static <T> ToOptional<T> get() {
- return (ToOptional<T>) INSTANCE;
- }
- static class Ref<RT> {
- private RT value;
- private int count = 0;
- public void set(RT value) {
- this.value = value;
- this.count++;
- }
- public RT get() {
- return this.value;
- }
- public int getCount() {
- return this.count;
- }
- }
- @Override
- public Supplier<Ref<T>> supplier() {
- return Ref<T>::new;
- }
- @Override
- public BiConsumer<Ref<T>, T> accumulator() {
- return (ref, value) -> {
- ref.set(value);
- };
- }
- @Override
- public BinaryOperator<Ref<T>> combiner() {
- return (ref1, ref2) -> {
- if (ref1.getCount() == 0)
- return ref2;
- if (ref2.getCount() == 0)
- return ref1;
- ref1.set(null);// increments count
- return ref1;
- };
- }
- @Override
- public Function<Ref<T>, Optional<T>> finisher() {
- return (ref) -> {
- if (ref.getCount() != 1)
- return Optional.empty();
- return Optional.ofNullable(ref.get());
- };
- }
- @Override
- public Set<java.util.stream.Collector.Characteristics> characteristics() {
- return Collections.emptySet();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement