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

net.jqwik.engine.support.JqwikStreamSupport Maven / Gradle / Ivy

There is a newer version: 1.9.1
Show newest version
package net.jqwik.engine.support;

import java.util.*;
import java.util.concurrent.atomic.*;
import java.util.function.*;
import java.util.stream.*;

public class JqwikStreamSupport {

	/**
	 * From https://stackoverflow.com/a/46230233/32352
	 *
	 * @param leftStream left
	 * @param rightStream right
	 * @param combiner combine
	 * @param  left type
	 * @param  right type
	 * @param  result type
	 * @return a zipped stream
	 */
	public static  Stream zip(Stream leftStream, Stream rightStream, BiFunction combiner) {
		Spliterator lefts = leftStream.spliterator();
		Spliterator rights = rightStream.spliterator();
		return StreamSupport.stream(
			new Spliterators.AbstractSpliterator(
				Long.min(lefts.estimateSize(), rights.estimateSize()),
				lefts.characteristics() & rights.characteristics()
			) {
				@Override
				public boolean tryAdvance(Consumer action) {
					return lefts.tryAdvance(left -> rights.tryAdvance(right -> {
						T combinedValue = combiner.apply(left, right);
						if (combinedValue == null) {
							return;
						}
						action.accept(combinedValue);
					}));
				}
			}, leftStream.isParallel() || rightStream.isParallel());
	}

	@SafeVarargs
	public static  Stream concat(Stream... streams) {
		return concat(Arrays.asList(streams));
	}

	/**
	 * Use only if normal concatenating will overflow the stack with too many streams
	 *
	 * @param suppliers stream supplier
	 * @param  type
	 * @return a stream
	 */
	public static  Stream lazyConcat(List>> suppliers) {
		return suppliers.stream().flatMap(Supplier::get);
	}

	public static  Stream concat(List> streams) {
		return concat(Stream.empty(), new ArrayList<>(streams));
	}

	private static  Stream concat(Stream head, List> rest) {
		if (rest.isEmpty()) {
			return head;
		}
		Stream first = rest.remove(0);
		return Stream.concat(head, concat(first, rest));
	}

	/**
	 * Simulates Java 9's Stream.takeWhile()
	 * Taken from https://stackoverflow.com/a/46446546/32352
	 *
	 * TODO: Remove when moving to Java > 8
	 *
	 * @param stream a stream
	 * @param p a predicate
	 * @param  a type
	 * @return a stream
	 */
	public static  Stream takeWhile(Stream stream, Predicate p) {
		class Taking extends Spliterators.AbstractSpliterator implements Consumer {
			private static final int CANCEL_CHECK_COUNT = 63;
			private final Spliterator s;
			private int count;
			private T t;
			private final AtomicBoolean cancel = new AtomicBoolean();
			private boolean takeOrDrop = true;

			Taking(Spliterator s) {
				super(s.estimateSize(), s.characteristics() & ~(Spliterator.SIZED | Spliterator.SUBSIZED));
				this.s = s;
			}

			@Override
			public boolean tryAdvance(Consumer action) {
				boolean test = true;
				if (takeOrDrop &&               // If can take
						(count != 0 || !cancel.get()) && // and if not cancelled
						s.tryAdvance(this) &&   // and if advanced one element
						(test = p.test(t))) {   // and test on element passes
					action.accept(t);           // then accept element
					return true;
				} else {
					// Taking is finished
					takeOrDrop = false;
					// Cancel all further traversal and splitting operations
					// only if test of element failed (short-circuited)
					if (!test)
						cancel.set(true);
					return false;
				}
			}

			@Override
			public Comparator getComparator() {
				return s.getComparator();
			}

			@Override
			public void accept(T t) {
				count = (count + 1) & CANCEL_CHECK_COUNT;
				this.t = t;
			}

			@Override
			public Spliterator trySplit() {
				return null;
			}
		}
		return StreamSupport.stream(new Taking(stream.spliterator()), stream.isParallel()).onClose(stream::close);
	}

	public static  Stream toStream(Optional optional) {
		return optional.map(Stream::of).orElse(Stream.empty());
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy