/** * Inner join stream with itself. * <p> * <code><pre> * // (tuple(1, 1), tuple(2, 2)) * Seq.of(1, 2).innerSelfJoin((t, u) -> Objects.equals(t, u)) * </pre></code> */ default Seq<Tuple2<T, T>> innerSelfJoin(BiPredicate<? super T, ? super T> predicate) { SeqBuffer<T> buffer = SeqBuffer.of(this); return buffer.seq().innerJoin(buffer.seq(), predicate); }
/** * Left outer join one streams into itself. * <p> * <code><pre> * // (tuple(tuple(1, 0), NULL), tuple(tuple(2, 1), tuple(1, 0))) * Seq.of(new Tuple2<Integer, Integer>(1, 0), new Tuple2<Integer, Integer>(2, 1)).leftOuterSelfJoin((t, u) -> Objects.equals(t.v2, u.v1)) * </pre></code> */ default Seq<Tuple2<T, T>> leftOuterSelfJoin(BiPredicate<? super T, ? super T> predicate) { SeqBuffer<T> buffer = SeqBuffer.of(this); return buffer.seq().leftOuterJoin(buffer.seq(), predicate); }
/** * Left outer join one streams into itself. * <p> * <code><pre> * // (tuple(tuple(1, 0), NULL), tuple(tuple(2, 1), tuple(1, 0))) * Seq.of(new Tuple2<Integer, Integer>(1, 0), new Tuple2<Integer, Integer>(2, 1)).leftOuterSelfJoin((t, u) -> Objects.equals(t.v2, u.v1)) * </pre></code> */ default Seq<Tuple2<T, T>> leftOuterSelfJoin(BiPredicate<? super T, ? super T> predicate) { SeqBuffer<T> buffer = SeqBuffer.of(this); return buffer.seq().leftOuterJoin(buffer.seq(), predicate); }
/** * Duplicate a Streams into two equivalent Streams. * <p> * <code><pre> * // tuple((1, 2, 3), (1, 2, 3)) * Seq.of(1, 2, 3).duplicate() * </pre></code> */ static <T> Tuple2<Seq<T>, Seq<T>> duplicate(Stream<? extends T> stream) { SeqBuffer<T> buffer = SeqBuffer.of(stream); return tuple(buffer.seq(), buffer.seq()); }
/** * Cross join stream with itself into one. * <p> * <code><pre> * // (tuple(1, 1), tuple(1, 2), tuple(2, 1), tuple(2, 2)) * Seq.of(1, 2).crossSelfJoin() * </pre></code> */ default Seq<Tuple2<T, T>> crossSelfJoin() { SeqBuffer<T> buffer = SeqBuffer.of(this); return crossJoin(buffer.seq(), buffer.seq()); }
/** * Inner join stream with itself. * <p> * <code><pre> * // (tuple(1, 1), tuple(2, 2)) * Seq.of(1, 2).innerSelfJoin((t, u) -> Objects.equals(t, u)) * </pre></code> */ default Seq<Tuple2<T, T>> innerSelfJoin(BiPredicate<? super T, ? super T> predicate) { SeqBuffer<T> buffer = SeqBuffer.of(this); return buffer.seq().innerJoin(buffer.seq(), predicate); }
/** * Cross join stream with itself into one. * <p> * <code><pre> * // (tuple(1, 1), tuple(1, 2), tuple(2, 1), tuple(2, 2)) * Seq.of(1, 2).crossSelfJoin() * </pre></code> */ default Seq<Tuple2<T, T>> crossSelfJoin() { SeqBuffer<T> buffer = SeqBuffer.of(this); return crossJoin(buffer.seq(), buffer.seq()); }
/** * Duplicate a Streams into two equivalent Streams. * <p> * <code><pre> * // tuple((1, 2, 3), (1, 2, 3)) * Seq.of(1, 2, 3).duplicate() * </pre></code> */ static <T> Tuple2<Seq<T>, Seq<T>> duplicate(Stream<? extends T> stream) { SeqBuffer<T> buffer = SeqBuffer.of(stream); return tuple(buffer.seq(), buffer.seq()); }
/** * Split a stream at a given position. * <p> * <code><pre> * // tuple((1, 2, 3), (4, 5, 6)) * Seq.of(1, 2, 3, 4, 5, 6).splitAt(3) * </pre></code> */ static <T> Tuple2<Seq<T>, Seq<T>> splitAt(Stream<? extends T> stream, long position) { SeqBuffer<T> buffer = SeqBuffer.of(stream); return tuple(buffer.seq().limit(position), buffer.seq().skip(position)); }
/** * Split a stream at a given position. * <p> * <code><pre> * // tuple((1, 2, 3), (4, 5, 6)) * Seq.of(1, 2, 3, 4, 5, 6).splitAt(3) * </pre></code> */ static <T> Tuple2<Seq<T>, Seq<T>> splitAt(Stream<? extends T> stream, long position) { SeqBuffer<T> buffer = SeqBuffer.of(stream); return tuple(buffer.seq().limit(position), buffer.seq().skip(position)); }
/** * Inner join 2 streams into one. * <p> * <code><pre> * // (tuple(1, 1), tuple(2, 2)) * Seq.of(1, 2, 3).innerJoin(Seq.of(1, 2), (t, u) -> Objects.equals(t, u)) * </pre></code> */ default <U> Seq<Tuple2<T, U>> innerJoin(Seq<? extends U> other, BiPredicate<? super T, ? super U> predicate) { // This algorithm has substantial complexity for large argument streams! SeqBuffer<? extends U> buffer = SeqBuffer.of(other); return flatMap(t -> buffer.seq() .filter(u -> predicate.test(t, u)) .map(u -> Tuple.<T, U>tuple(t, u))) .onClose(other::close); }
/** * Inner join 2 streams into one. * <p> * <code><pre> * // (tuple(1, 1), tuple(2, 2)) * Seq.of(1, 2, 3).innerJoin(Seq.of(1, 2), (t, u) -> Objects.equals(t, u)) * </pre></code> */ default <U> Seq<Tuple2<T, U>> innerJoin(Seq<? extends U> other, BiPredicate<? super T, ? super U> predicate) { // This algorithm has substantial complexity for large argument streams! SeqBuffer<? extends U> buffer = SeqBuffer.of(other); return flatMap(t -> buffer.seq() .filter(u -> predicate.test(t, u)) .map(u -> Tuple.<T, U>tuple(t, u))) .onClose(other::close); }
/** * Left outer join 2 streams into one. * <p> * <code><pre> * // (tuple(1, 1), tuple(2, 2), tuple(3, null)) * Seq.of(1, 2, 3).leftOuterJoin(Seq.of(1, 2), (t, u) -> Objects.equals(t, u)) * </pre></code> */ default <U> Seq<Tuple2<T, U>> leftOuterJoin(Seq<? extends U> other, BiPredicate<? super T, ? super U> predicate) { // This algorithm has substantial complexity for large argument streams! SeqBuffer<? extends U> buffer = SeqBuffer.of(other); return flatMap(t -> buffer.seq() .filter(u -> predicate.test(t, u)) .onEmpty(null) .map(u -> Tuple.<T, U>tuple(t, u))) .onClose(other::close); }
/** * Left outer join 2 streams into one. * <p> * <code><pre> * // (tuple(1, 1), tuple(2, 2), tuple(3, null)) * Seq.of(1, 2, 3).leftOuterJoin(Seq.of(1, 2), (t, u) -> Objects.equals(t, u)) * </pre></code> */ default <U> Seq<Tuple2<T, U>> leftOuterJoin(Seq<? extends U> other, BiPredicate<? super T, ? super U> predicate) { // This algorithm has substantial complexity for large argument streams! SeqBuffer<? extends U> buffer = SeqBuffer.of(other); return flatMap(t -> buffer.seq() .filter(u -> predicate.test(t, u)) .onEmpty(null) .map(u -> Tuple.<T, U>tuple(t, u))) .onClose(other::close); }