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

org.perfectable.introspection.query.Streams Maven / Gradle / Ivy

There is a newer version: 5.1.0
Show newest version
package org.perfectable.introspection.query;

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Enumeration;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

final class Streams {
	static  Stream generateSingle(E initial,
										Function> mutator) {
		return generate(Stream.of(initial), mutator, element -> true);
	}

	static  Stream generateSingleConditional(E initial,
												   Function> mutator,
												   Predicate condition) {
		return generate(Stream.of(initial), mutator, condition);
	}

	private static  Stream generate(Stream initial,
										  Function> mutator,
										  Predicate condition) {
		Spliterator wrappedSpliterator =
			GeneratorSpliterator.wrap(initial.spliterator(), mutator, condition);
		return StreamSupport.stream(wrappedSpliterator, /* parallel= */false);
	}

	public static  Stream from(Enumeration enumeration) {
		Spliterator spliterator = EnumerationSpliterator.create(enumeration);
		return StreamSupport.stream(spliterator, /* parallel= */false);
	}

	private static final class GeneratorSpliterator extends Spliterators.AbstractSpliterator {
		private static final int ADDITIONAL_CHARACTERISTICS = 0;

		private final Spliterator wrapped;
		private final Function> mutator;
		private final Predicate condition;
		private final Deque buffer = new ArrayDeque<>();

		static  GeneratorSpliterator wrap(Spliterator wrapped,
												Function> mutator,
												Predicate condition) {
			return new GeneratorSpliterator<>(wrapped, mutator, condition);
		}

		private GeneratorSpliterator(Spliterator wrapped,
									 Function> mutator,
									 Predicate condition) {
			super(Long.MAX_VALUE, ADDITIONAL_CHARACTERISTICS);
			this.wrapped = wrapped;
			this.mutator = mutator;
			this.condition = condition;
		}

		@Override
		public boolean tryAdvance(Consumer consumer) {
			Consumer wrappedAction = element -> {
				consumer.accept(element);
				mutator.apply(element).filter(condition).forEach(buffer::add);
			};
			if (buffer.isEmpty()) {
				return wrapped.tryAdvance(wrappedAction);
			}
			else {
				T generated = buffer.pop();
				wrappedAction.accept(generated);
				return true;
			}
		}
	}

	private static final class EnumerationSpliterator extends Spliterators.AbstractSpliterator {
		private static final int ADDITIONAL_CHARACTERISTICS = 0;

		private final Enumeration enumeration;

		private EnumerationSpliterator(Enumeration enumeration) {
			super(Long.MAX_VALUE, ADDITIONAL_CHARACTERISTICS);
			this.enumeration = enumeration;
		}

		public static  Spliterator create(Enumeration enumeration) {
			return new EnumerationSpliterator(enumeration);
		}

		@Override
		public boolean tryAdvance(Consumer consumer) {
			if (!enumeration.hasMoreElements()) {
				return false;
			}
			E nextElement = enumeration.nextElement();
			consumer.accept(nextElement);
			return true;
		}
	}

	private Streams() {
		// utility
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy