com.slimgears.util.stream.Streams Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of stream-utils Show documentation
Show all versions of stream-utils Show documentation
General purpose utils / module: stream-utils
package com.slimgears.util.stream;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
@SuppressWarnings("WeakerAccess")
public class Streams {
public static Stream> toBatch(Stream source, int batchSize) {
Spliterator> batchSpliterator = batch(source.spliterator(), batchSize);
return StreamSupport.stream(batchSpliterator, false)
.map(spliterator -> StreamSupport.stream(spliterator, false));
}
public static Stream ofType(Class clazz, Stream source) {
return source.filter(clazz::isInstance).map(clazz::cast);
}
public static Function> ofType(Class clazz) {
return item -> ofType(clazz, Stream.of(item));
}
public static Function self() {
return s -> s;
}
public static Stream takeWhile(Stream stream, Predicate super T> predicate) {
return StreamSupport.stream(takeWhile(stream.spliterator(), predicate), false);
}
public static Stream fromIterator(Iterator iterator) {
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false);
}
public static Stream fromIterable(Iterable iterable) {
return fromIterator(iterable.iterator());
}
public static Stream fromEnumeration(Enumeration enumeration) {
return StreamSupport.stream(
new Spliterators.AbstractSpliterator(Long.MAX_VALUE, Spliterator.ORDERED) {
public boolean tryAdvance(Consumer super T> action) {
if(enumeration.hasMoreElements()) {
action.accept(enumeration.nextElement());
return true;
}
return false;
}
public void forEachRemaining(Consumer super T> action) {
while(enumeration.hasMoreElements()) action.accept(enumeration.nextElement());
}
}, false);
}
public static Stream orderByTopology(Stream source, Function> childrenGetter) {
return orderByTopology(source, childrenGetter, new HashSet<>());
}
private static Stream orderByTopology(Stream source, Function> childrenGetter, Set visited) {
return source
.filter(visited::add)
.flatMap(val -> Stream.concat(orderByTopology(childrenGetter.apply(val), childrenGetter, visited), Stream.of(val)));
}
private static Spliterator takeWhile(Spliterator spliterator, Predicate super T> predicate) {
return new Spliterators.AbstractSpliterator(spliterator.estimateSize(), 0) {
private boolean finished = false;
@Override
public boolean tryAdvance(Consumer super T> action) {
return spliterator.tryAdvance(item -> {
if (predicate.test(item)) {
action.accept(item);
} else {
finished = true;
}
}) && !finished;
}
};
}
static class LimitedSpliterator extends Spliterators.AbstractSpliterator {
private final Spliterator source;
private final AtomicInteger remaining;
private final AtomicBoolean finished = new AtomicBoolean(false);
LimitedSpliterator(Spliterator source, int maxSize) {
super(maxSize, 0);
this.source = source;
this.remaining = new AtomicInteger(maxSize);
}
@Override
public boolean tryAdvance(Consumer super T> action) {
if (remaining.decrementAndGet() == 0) {
return false;
}
finished.set(source.tryAdvance(action));
return finished.get();
}
}
private static Spliterator> batch(Spliterator source, int batchSize) {
return new Spliterators.AbstractSpliterator>(source.estimateSize() / batchSize, 0) {
@Override
public boolean tryAdvance(Consumer super Spliterator> action) {
LimitedSpliterator spliterator = new LimitedSpliterator<>(source, batchSize);
action.accept(spliterator);
return !spliterator.finished.get();
}
};
}
}