
com.github.phantomthief.util.CursorIteratorEx Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cursor-iterator Show documentation
Show all versions of cursor-iterator Show documentation
A cursor iterator implements for batch build cursor data
The newest version!
/**
*
*/
package com.github.phantomthief.util;
import java.util.Iterator;
import java.util.Objects;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
/**
* @author w.vela
*/
public class CursorIteratorEx implements Iterable {
private final C initCursor;
private final boolean checkFirstCursor;
private final Function dataRetriever;
private final Function cursorExtractor;
private final Function> dataExtractor;
private final Predicate endChecker;
/**
* @param initCursor
* @param checkFirstCursor
* @param dataRetriever
* @param cursorExtractor
* @param dataExtractor
* @param endChecker
*/
private CursorIteratorEx(C initCursor, boolean checkFirstCursor, Function dataRetriever,
Function cursorExtractor, Function> dataExtractor,
Predicate endChecker) {
this.initCursor = initCursor;
this.checkFirstCursor = checkFirstCursor;
this.dataRetriever = dataRetriever;
this.cursorExtractor = cursorExtractor;
this.dataExtractor = dataExtractor;
this.endChecker = endChecker;
}
private final class RollingIterator implements Iterator {
private C currentCursor;
private R currentData;
private Iterator currentIterator;
public RollingIterator() {
currentCursor = initCursor;
if (checkFirstCursor && endChecker.test(currentCursor)) {
return;
}
currentData = dataRetriever.apply(currentCursor);
if (currentData != null) {
currentIterator = dataExtractor.apply(currentData);
currentCursor = cursorExtractor.apply(currentData);
}
}
/* (non-Javadoc)
* @see java.util.Iterator#hasNext()
*/
@Override
public boolean hasNext() {
if (currentIterator == null) {
return false;
}
if (currentIterator.hasNext()) {
return true;
}
roll();
return currentIterator != null && currentIterator.hasNext();
}
private void roll() {
if (endChecker.test(currentCursor)) {
currentData = null;
currentIterator = null;
return;
}
currentData = dataRetriever.apply(currentCursor);
if (currentData == null) {
currentIterator = null;
} else {
currentCursor = cursorExtractor.apply(currentData);
currentIterator = dataExtractor.apply(currentData);
}
}
/* (non-Javadoc)
* @see java.util.Iterator#next()
*/
@Override
public T next() {
return currentIterator.next();
}
}
/* (non-Javadoc)
* @see java.lang.Iterable#iterator()
*/
@Override
public Iterator iterator() {
return new RollingIterator();
}
public Stream stream() {
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator(),
(Spliterator.NONNULL | Spliterator.IMMUTABLE)), false);
}
@SuppressWarnings("unchecked")
public static final class Builder {
private C initCursor;
private boolean checkFirstCursor;
private Function dataRetriever;
private Function cursorExtractor;
private Function> dataExtractor;
private Predicate endChecker;
public Builder, C1, ?> withInitCursor(C1 initCursor) {
Builder, C1, ?> thisBuilder = (Builder, C1, ?>) this;
thisBuilder.initCursor = initCursor;
return thisBuilder;
}
public Builder firstCursorCheckEnd(boolean check) {
this.checkFirstCursor = check;
return this;
}
public Builder, C1, R1> withDataRetriever(Function dataRetriever) {
Builder, C1, R1> thisBuilder = (Builder, C1, R1>) this;
thisBuilder.dataRetriever = dataRetriever;
return thisBuilder;
}
public Builder, C1, R1> withCursorExtractor(Function cursorExtractor) {
Builder, C1, R1> thisBuilder = (Builder, C1, R1>) this;
thisBuilder.cursorExtractor = cursorExtractor;
return thisBuilder;
}
public Builder
withDataExtractor(Function> dataExtractor) {
Builder thisBuilder = (Builder) this;
thisBuilder.dataExtractor = dataExtractor;
return thisBuilder;
}
public Builder, C1, ?> withEndChecker(Predicate endChecker) {
Builder, C1, ?> thisBuilder = (Builder, C1, ?>) this;
thisBuilder.endChecker = endChecker;
return thisBuilder;
}
@SuppressWarnings("rawtypes")
public CursorIteratorEx build() {
ensure();
return new CursorIteratorEx(initCursor, checkFirstCursor, dataRetriever,
cursorExtractor, dataExtractor, endChecker);
}
private void ensure() {
if (dataExtractor == null) {
throw new NullPointerException("data extractor is null.");
}
if (dataRetriever == null) {
throw new NullPointerException("data retriver is null.");
}
if (cursorExtractor == null) {
throw new NullPointerException("data retriver is null.");
}
if (endChecker == null) {
endChecker = Objects::isNull;
}
}
}
public static final Builder
© 2015 - 2025 Weber Informatics LLC | Privacy Policy