private static <T> Stream<T> takeWhile(List<T> src, Predicate<T> p) { Spliterator<T> iter = src.spliterator(); Spliterator<T> res = new AbstractSpliterator<T>(Long.MAX_VALUE, Spliterator.ORDERED) { private boolean hasNext = true; @Override public boolean tryAdvance(Consumer<? super T> action) { if(hasNext) return iter.tryAdvance(item -> { if(p.test(item)) action.accept(item); else hasNext = false; }) && hasNext; return false; } }; return StreamSupport.stream(res, false); }
public static <T> Stream<T> distinct(Stream<T> src, Comparator<T> cmp) { Spliterator<T> iter = src.spliterator(); Spliterator<T> res = new AbstractSpliterator<T>(Long.MAX_VALUE, Spliterator.ORDERED ) { // ArrayList<T> distinctData = new ArrayList<>(); TreeSet<T> distinctData = new TreeSet<>(cmp); @Override public boolean tryAdvance(Consumer<? super T> action) { return iter.tryAdvance( item -> { // Versão 1: if (!contains(distinctData, cmp, item)) { // Versão 2: if(!distinctData.stream().anyMatch(e -> cmp.compare(e, item) == 0)) { // Versão 3: if (!distinctData.contains(item)) { distinctData.add(item); action.accept(item); } }); } }; return StreamSupport.stream(res, false); }
/** * Returns a stream in which each element is the result of passing the corresponding elementY of * each of {@code streamA} and {@code streamB} to {@code function}. * * <p>For example: * * <pre>{@code * Streams.zip( * Stream.of("foo1", "foo2", "foo3"), * Stream.of("bar1", "bar2"), * (arg1, arg2) -> arg1 + ":" + arg2) * }</pre> * * <p>will return {@code Stream.of("foo1:bar1", "foo2:bar2")}. * * <p>The resulting stream will only be as long as the shorter of the two input streams; if one * stream is longer, its extra elements will be ignored. * * <p>Note that if you are calling {@link Stream#forEach} on the resulting stream, you might want * to consider using {@link #forEachPair} instead of this method. * * <p><b>Performance note:</b> The resulting stream is not <a * href="http://gee.cs.oswego.edu/dl/html/StreamParallelGuidance.html">efficiently splittable</a>. * This may harm parallel performance. */ public static <A, B, R> Stream<R> zip( Stream<A> streamA, Stream<B> streamB, BiFunction<? super A, ? super B, R> function) { checkNotNull(streamA); checkNotNull(streamB); checkNotNull(function); boolean isParallel = streamA.isParallel() || streamB.isParallel(); // same as Stream.concat Spliterator<A> splitrA = streamA.spliterator(); Spliterator<B> splitrB = streamB.spliterator(); int characteristics = splitrA.characteristics() & splitrB.characteristics() & (Spliterator.SIZED | Spliterator.ORDERED); Iterator<A> itrA = Spliterators.iterator(splitrA); Iterator<B> itrB = Spliterators.iterator(splitrB); return StreamSupport.stream( new AbstractSpliterator<R>( Math.min(splitrA.estimateSize(), splitrB.estimateSize()), characteristics) { @Override public boolean tryAdvance(Consumer<? super R> action) { if (itrA.hasNext() && itrB.hasNext()) { action.accept(function.apply(itrA.next(), itrB.next())); return true; } return false; } }, isParallel); }
private static <T> Stream<T> concat(Stream<T> first, Stream<T> second) { Spliterator<T> iter1 = first.spliterator(); Spliterator<T> iter2 = second.spliterator(); Spliterator<T> iter = new AbstractSpliterator<T>(Long.MAX_VALUE, Spliterator.ORDERED) { boolean firstFinished = false; @Override public boolean tryAdvance(Consumer<? super T> action) { if(!firstFinished && iter1.tryAdvance(action)) return true; firstFinished = true; return iter2.tryAdvance(action); } }; return StreamSupport.stream(iter, false); }
public static <T> Stream<T> filterEvenLine(Stream<T> src) { Spliterator<T> iter = src.spliterator(); Spliterator<T> res = new AbstractSpliterator<T>(Long.MAX_VALUE, Spliterator.ORDERED ) { @Override public boolean tryAdvance(Consumer<? super T> action) { return iter.tryAdvance(item -> {}) ? iter.tryAdvance(action) : false; } }; return StreamSupport.stream(res, false); }
public static <T> Stream<T> distinct(Stream<T> src, Comparator<T> cmp) { Spliterator<T> iter = src.spliterator(); Spliterator<T> res = new AbstractSpliterator<T>(Long.MAX_VALUE, Spliterator.ORDERED ) { @Override public boolean tryAdvance(Consumer<? super T> action) { return false; } }; return StreamSupport.stream(res, false); }
/** * Returns a stream in which each element is the result of passing the corresponding element of * each of {@code streamA} and {@code streamB} to {@code function}. * * <p>For example: * * <pre>{@code * Streams.zip( * Stream.of("foo1", "foo2", "foo3"), * Stream.of("bar1", "bar2"), * (arg1, arg2) -> arg1 + ":" + arg2) * }</pre> * * <p>will return {@code Stream.of("foo1:bar1", "foo2:bar2")}. * * <p>The resulting stream will only be as long as the shorter of the two input streams; if one * stream is longer, its extra elements will be ignored. * * <p>The resulting stream is not <a * href="http://gee.cs.oswego.edu/dl/html/StreamParallelGuidance.html">efficiently splittable</a>. * This may harm parallel performance. */ public static <A, B, R> Stream<R> zip( Stream<A> streamA, Stream<B> streamB, BiFunction<? super A, ? super B, R> function) { checkNotNull(streamA); checkNotNull(streamB); checkNotNull(function); boolean isParallel = streamA.isParallel() || streamB.isParallel(); // same as Stream.concat Spliterator<A> splitrA = streamA.spliterator(); Spliterator<B> splitrB = streamB.spliterator(); int characteristics = splitrA.characteristics() & splitrB.characteristics() & (Spliterator.SIZED | Spliterator.ORDERED); Iterator<A> itrA = Spliterators.iterator(splitrA); Iterator<B> itrB = Spliterators.iterator(splitrB); return StreamSupport.stream( new AbstractSpliterator<R>( Math.min(splitrA.estimateSize(), splitrB.estimateSize()), characteristics) { @Override public boolean tryAdvance(Consumer<? super R> action) { if (itrA.hasNext() && itrB.hasNext()) { action.accept(function.apply(itrA.next(), itrB.next())); return true; } return false; } }, isParallel); }
/** * Returns a stream in which each element is the result of passing the corresponding elementY of * each of {@code streamA} and {@code streamB} to {@code function}. * * <p>For example: * * <pre>{@code * Streams.zip( * Stream.of("foo1", "foo2", "foo3"), * Stream.of("bar1", "bar2"), * (arg1, arg2) -> arg1 + ":" + arg2) * }</pre> * * <p>will return {@code Stream.of("foo1:bar1", "foo2:bar2")}. * * <p>The resulting stream will only be as long as the shorter of the two input streams; if one * stream is longer, its extra elements will be ignored. * * <p>Note that if you are calling {@link Stream#forEach} on the resulting stream, you might want * to consider using {@link #forEachPair} instead of this method. * * <p><b>Performance note:</b> The resulting stream is not <a * href="http://gee.cs.oswego.edu/dl/html/StreamParallelGuidance.html">efficiently splittable</a>. * This may harm parallel performance. */ public static <A, B, R> Stream<R> zip( Stream<A> streamA, Stream<B> streamB, BiFunction<? super A, ? super B, R> function) { checkNotNull(streamA); checkNotNull(streamB); checkNotNull(function); boolean isParallel = streamA.isParallel() || streamB.isParallel(); // same as Stream.concat Spliterator<A> splitrA = streamA.spliterator(); Spliterator<B> splitrB = streamB.spliterator(); int characteristics = splitrA.characteristics() & splitrB.characteristics() & (Spliterator.SIZED | Spliterator.ORDERED); Iterator<A> itrA = Spliterators.iterator(splitrA); Iterator<B> itrB = Spliterators.iterator(splitrB); return StreamSupport.stream( new AbstractSpliterator<R>( Math.min(splitrA.estimateSize(), splitrB.estimateSize()), characteristics) { @Override public boolean tryAdvance(Consumer<? super R> action) { if (itrA.hasNext() && itrB.hasNext()) { action.accept(function.apply(itrA.next(), itrB.next())); return true; } return false; } }, isParallel) .onClose(streamA::close) .onClose(streamB::close); }