public final static <T,C extends Comparable<? super C>> Optional<T> minBy(Stream<T> stream,Function<T,C> f){ Optional<Pair<C,T>> o = stream.map(in->new Pair<C,T>(f.apply(in),in)).min(Comparator.comparing(n->n._1(),Comparator.naturalOrder())); return o.map(p->p._2()); } public final static<T> Optional<T> min(Stream<T> stream,Comparator<? super T> comparator){
public final static <T,C extends Comparable<? super C>> Optional<T> maxBy(Stream<T> stream,Function<T,C> f){ Optional<Pair<C,T>> o = stream.map(in->new Pair<C,T>(f.apply(in),in)).max(Comparator.comparing(n->n._1(),Comparator.naturalOrder())); return o.map(p->p._2()); } public final static<T> Optional<T> max(Stream<T> stream,Comparator<? super T> comparator){
/** * zip 3 Streams into one * <pre> * {@code * List<Triple<Integer,Integer,Character>> list = of(1,2,3,4,5,6).zip3(of(100,200,300,400),of('a','b','c')) .collect(Collectors.toList()); * * //[[1,100,'a'],[2,200,'b'],[3,300,'c']] * } * *</pre> */ public final <S,U> SequenceM<Triple<T,S,U>> zip3(Stream<? extends S> second,Stream<? extends U> third){ return zip(second).zip(third).map(p -> new Triple(p._1()._1(),p._1()._2(),p._2())); } /**
/** * zip 4 Streams into 1 * * <pre> * {@code * List<Quadruple<Integer,Integer,Character,String>> list = of(1,2,3,4,5,6).zip4(of(100,200,300,400),of('a','b','c'),of("hello","world")) .collect(Collectors.toList()); * } * //[[1,100,'a',"hello"],[2,200,'b',"world"]] * </pre> */ public final <T2,T3,T4> SequenceM<Quadruple<T,T2,T3,T4>> zip4(Stream<T2> second,Stream<T3> third,Stream<T4> fourth){ return zip3(second,third).zip(fourth).map(t -> new Quadruple(t._1()._1(), t._1()._2(),t._1()._3(),t._2())); } /**
final BiConsumer accumulator = (acc,next) -> { LazySeq.of(collectors.stream().iterator()).<Object,Pair<Collector,Object>>zip(LazySeq.of((List)acc),(a,b)->new Pair<Collector,Object>(a,b)) .forEach( t -> t._1().accumulator().accept(t._2(),next)); }; final BinaryOperator combiner = (t1,t2)-> {
private final Pair<SequenceM<T>,SequenceM<T>> duplicatePos(int pos){ Pair<Iterator<T>,Iterator<T>> pair = StreamUtils.toBufferingDuplicator(monad.iterator(),pos); return new Pair(new SequenceM(StreamUtils.stream(pair._1())),new SequenceM(StreamUtils.stream(pair._2()))); } /**
/** * Duplicate a Stream, buffers intermediate values, leaders may change positions so a limit * can be safely applied to the leading stream. Not thread-safe. * <pre> * {@code * Pair<SequenceM<Integer>, SequenceM<Integer>> copies =of(1,2,3,4,5,6).duplicate(); assertTrue(copies.v1.anyMatch(i->i==2)); assertTrue(copies.v2.anyMatch(i->i==2)); * * } * </pre> * * @return duplicated stream */ public final Pair<SequenceM<T>,SequenceM<T>> duplicate(){ Pair<Iterator<T>,Iterator<T>> pair = StreamUtils.toBufferingDuplicator(monad.iterator()); return new Pair(new SequenceM(StreamUtils.stream(pair._1())),new SequenceM(StreamUtils.stream(pair._2()))); } private final Pair<SequenceM<T>,SequenceM<T>> duplicatePos(int pos){