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 org.jspecify.annotations.*;

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) {
		// See discussion in https://github.com/jqwik-team/jqwik/issues/526 why StreamConcatenation is used
		return StreamConcatenation.concat(streams);
	}

	@SuppressWarnings("unchecked")
	public static  Stream concat(List> streams) {
		return concat(streams.toArray(new Stream[0]));
	}

	/**
	 * 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