![JAR search and dependency download from the Maven repository](/logo.png)
xdean.jex.extra.rx2.RxIterator Maven / Gradle / Ivy
The newest version!
package xdean.jex.extra.rx2;
import static xdean.jex.util.lang.ExceptionUtil.uncheck;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.concurrent.LinkedBlockingQueue;
import org.reactivestreams.Subscription;
import io.reactivex.Flowable;
import io.reactivex.Notification;
import io.reactivex.Observable;
import io.reactivex.Scheduler;
import io.reactivex.annotations.SchedulerSupport;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
/**
* Convert RxStream to Iterator.
*
* @author XDean, Michael@stackoverflow
*
*/
public class RxIterator {
public static Function, Iterator> flowableIterator() {
return o -> toIterator(o);
}
public static Iterator toIterator(Flowable ob) {
return new FlowableIterator<>(ob);
}
public static Function, Iterator> observableIterator(Scheduler scheduler) {
return o -> toIterator(o, scheduler);
}
public static Function, Iterator> observableIterator() {
return o -> toIterator(o);
}
public static Iterator toIterator(Observable ob, Scheduler scheduler) {
return new ObservableIterator<>(ob, scheduler);
}
@SchedulerSupport(SchedulerSupport.IO)
public static Iterator toIterator(Observable ob) {
return toIterator(ob, Schedulers.io());
}
public static final class ObservableIterator implements Iterator {
private LinkedBlockingQueue> queue = new LinkedBlockingQueue<>();
private Notification next = null;
private boolean completed = false;
public ObservableIterator(Observable source, Scheduler scheduler) {
source
.materialize()
.subscribeOn(scheduler)
.subscribe(queue::put);
}
@Override
public boolean hasNext() {
calcNext();
return !completed;
}
@Override
public T next() {
calcNext();
if (next == null) {
throw new NoSuchElementException();
}
T t = next.getValue();
next = null;
return t;
}
private void calcNext() {
if (completed) {
return;
}
if (next == null) {
Notification take = uncheck(queue::take);
if (take.isOnNext()) {
next = take;
} else if (take.isOnError()) {
completed = true;
throw new RuntimeException(take.getError());
} else {
completed = true;
}
}
}
}
public static final class FlowableIterator implements Iterator {
private Notification next = null;
private LinkedBlockingQueue> queue = new LinkedBlockingQueue<>(1);
private boolean completed = false;
private Subscription subscription;
public FlowableIterator(Flowable source) {
source
.materialize()
.subscribe(
e -> queue.put(e),
e -> completed = true,
() -> completed = true,
s -> this.subscription = s
);
}
@Override
public boolean hasNext() {
calcNext();
return !completed;
}
@Override
public T next() {
calcNext();
if (next == null) {
throw new NoSuchElementException();
}
T t = next.getValue();
next = null;
return t;
}
private void calcNext() {
if (completed) {
return;
}
if (next == null) {
subscription.request(1);
Notification take = uncheck(() -> queue.take());
if (take.isOnNext()) {
next = take;
} else if (take.isOnError()) {
completed = true;
throw new RuntimeException(take.getError());
} else {
completed = true;
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy