com.landawn.abacus.util.BiIterator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of abacus-common Show documentation
Show all versions of abacus-common Show documentation
A general programming library in Java/Android. It's easy to learn and simple to use with concise and powerful APIs.
/*
* Copyright (c) 2018, Haiyang Li.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.landawn.abacus.util;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import com.landawn.abacus.util.Fn.Suppliers;
import com.landawn.abacus.util.function.IndexedConsumer;
import com.landawn.abacus.util.stream.Stream;
/**
*
* @author Haiyang Li
* @param
* @param
* @since 1.2.10
*/
public abstract class BiIterator extends ImmutableIterator> {
@SuppressWarnings("rawtypes")
private static final BiIterator EMPTY = new BiIterator() {
@Override
public boolean hasNext() {
return false;
}
@Override
public Object next() {
throw new NoSuchElementException();
}
@Override
public void forEachRemaining(Throwables.BiConsumer action) throws Exception {
N.checkArgNotNull(action);
}
@Override
public ObjIterator map(BiFunction mapper) {
N.checkArgNotNull(mapper);
return ObjIterator.empty();
}
};
/**
*
* @param
* @param
* @return
*/
public static BiIterator empty() {
return EMPTY;
}
/**
*
* @param the key type
* @param the value type
* @param map
* @return
*/
public static BiIterator of(final Map map) {
if (N.isNullOrEmpty(map)) {
return empty();
}
return of(map.entrySet().iterator());
}
/**
*
* @param the key type
* @param the value type
* @param iter
* @return
*/
public static BiIterator of(final Iterator> iter) {
if (iter == null) {
return empty();
}
return new BiIterator<>() {
@Override
public boolean hasNext() {
return iter.hasNext();
}
@Override
public Pair next() {
return Pair.from(iter.next());
}
@Override
public void forEachRemaining(final Throwables.BiConsumer super K, ? super V, E> action) throws E {
N.checkArgNotNull(action);
Map.Entry entry = null;
while (iter.hasNext()) {
entry = iter.next();
action.accept(entry.getKey(), entry.getValue());
}
}
@Override
public ObjIterator map(final BiFunction super K, ? super V, R> mapper) {
N.checkArgNotNull(mapper);
return new ObjIterator<>() {
private Map.Entry entry = null;
@Override
public boolean hasNext() {
return iter.hasNext();
}
@Override
public R next() {
entry = iter.next();
return mapper.apply(entry.getKey(), entry.getValue());
}
};
}
};
}
/**
* Returns an infinite {@code BiIterator}.
*
* @param
* @param
* @param output transfer the next values.
* @return
*/
public static BiIterator generate(final Consumer> output) {
return generate(com.landawn.abacus.util.function.BooleanSupplier.TRUE, output);
}
/**
*
* @param
* @param
* @param hasNext
* @param output
* @return
*/
public static BiIterator generate(final BooleanSupplier hasNext, final Consumer> output) {
N.checkArgNotNull(hasNext);
N.checkArgNotNull(output);
return new BiIterator<>() {
private final Pair tmp = new Pair<>();
@Override
public boolean hasNext() {
return hasNext.getAsBoolean();
}
@Override
public Pair next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
output.accept(tmp);
return Pair.of(tmp.left, tmp.right);
}
@Override
public void forEachRemaining(final Throwables.BiConsumer super A, ? super B, E> action) throws E {
N.checkArgNotNull(action);
while (hasNext.getAsBoolean()) {
output.accept(tmp);
action.accept(tmp.left, tmp.right);
}
}
@Override
public ObjIterator map(final BiFunction super A, ? super B, R> mapper) {
N.checkArgNotNull(mapper);
return new ObjIterator<>() {
@Override
public boolean hasNext() {
return hasNext.getAsBoolean();
}
@Override
public R next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
output.accept(tmp);
return mapper.apply(tmp.left, tmp.right);
}
};
}
};
}
/**
*
* @param
* @param
* @param fromIndex
* @param toIndex
* @param output
* @return
*/
public static BiIterator generate(final int fromIndex, final int toIndex, final IndexedConsumer> output) {
N.checkFromToIndex(fromIndex, toIndex, Integer.MAX_VALUE);
N.checkArgNotNull(output);
return new BiIterator<>() {
private final MutableInt cursor = MutableInt.of(fromIndex);
private final Pair tmp = new Pair<>();
@Override
public boolean hasNext() {
return cursor.value() < toIndex;
}
@Override
public Pair next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
output.accept(cursor.getAndIncrement(), tmp);
return Pair.of(tmp.left, tmp.right);
}
@Override
public void forEachRemaining(final Throwables.BiConsumer super A, ? super B, E> action) throws E {
N.checkArgNotNull(action);
while (cursor.value() < toIndex) {
output.accept(cursor.getAndIncrement(), tmp);
action.accept(tmp.left, tmp.right);
}
}
@Override
public ObjIterator map(final BiFunction super A, ? super B, R> mapper) {
N.checkArgNotNull(mapper);
return new ObjIterator<>() {
@Override
public boolean hasNext() {
return cursor.value() < toIndex;
}
@Override
public R next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
output.accept(cursor.getAndIncrement(), tmp);
return mapper.apply(tmp.left, tmp.right);
}
};
}
};
}
/**
*
* @param
* @param
* @param a
* @param b
* @return
*/
public static BiIterator zip(final A[] a, final B[] b) {
return zip(Array.asList(a), Array.asList(b));
}
/**
*
* @param
* @param
* @param a
* @param b
* @param valueForNoneA
* @param valueForNoneB
* @return
*/
public static BiIterator zip(final A[] a, final B[] b, final A valueForNoneA, final B valueForNoneB) {
return zip(Array.asList(a), Array.asList(b), valueForNoneA, valueForNoneB);
}
/**
*
* @param
* @param
* @param a
* @param b
* @return
*/
public static BiIterator zip(final Collection a, final Collection b) {
return zip(a == null ? null : a.iterator(), b == null ? null : b.iterator());
}
/**
*
* @param
* @param
* @param a
* @param b
* @param valueForNoneA
* @param valueForNoneB
* @return
*/
public static BiIterator zip(final Collection a, final Collection b, final A valueForNoneA, final B valueForNoneB) {
return zip(a == null ? null : a.iterator(), b == null ? null : b.iterator(), valueForNoneA, valueForNoneB);
}
/**
*
* @param
* @param
* @param iterA
* @param iterB
* @return
*/
public static BiIterator zip(final Iterator iterA, final Iterator iterB) {
if (iterA == null || iterB == null) {
return empty();
}
return new BiIterator<>() {
@Override
public boolean hasNext() {
return iterA.hasNext() && iterB.hasNext();
}
@Override
public Pair next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return Pair.of(iterA.next(), iterB.next());
}
@Override
public void forEachRemaining(final Throwables.BiConsumer super A, ? super B, E> action) throws E {
N.checkArgNotNull(action);
while (iterA.hasNext() && iterB.hasNext()) {
action.accept(iterA.next(), iterB.next());
}
}
@Override
public ObjIterator map(final BiFunction super A, ? super B, R> mapper) {
N.checkArgNotNull(mapper);
return new ObjIterator<>() {
@Override
public boolean hasNext() {
return iterA.hasNext() && iterB.hasNext();
}
@Override
public R next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return mapper.apply(iterA.next(), iterB.next());
}
};
}
};
}
/**
*
* @param
* @param
* @param iterA
* @param iterB
* @param valueForNoneA
* @param valueForNoneB
* @return
*/
public static BiIterator zip(final Iterator iterA, final Iterator iterB, final A valueForNoneA, final B valueForNoneB) {
final Iterator iter1 = iterA == null ? ObjIterator. empty() : iterA;
final Iterator iter2 = iterB == null ? ObjIterator. empty() : iterB;
return new BiIterator<>() {
@Override
public boolean hasNext() {
return iter1.hasNext() || iter2.hasNext();
}
@Override
public Pair next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return Pair.of(iter1.hasNext() ? iter1.next() : valueForNoneA, iter2.hasNext() ? iter2.next() : valueForNoneB);
}
@Override
public void forEachRemaining(final Throwables.BiConsumer super A, ? super B, E> action) throws E {
N.checkArgNotNull(action);
while (iter1.hasNext() || iter2.hasNext()) {
action.accept(iter1.hasNext() ? iter1.next() : valueForNoneA, iter2.hasNext() ? iter2.next() : valueForNoneB);
}
}
@Override
public ObjIterator map(final BiFunction super A, ? super B, R> mapper) {
N.checkArgNotNull(mapper);
return new ObjIterator<>() {
@Override
public boolean hasNext() {
return iter1.hasNext() || iter2.hasNext();
}
@Override
public R next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return mapper.apply(iter1.hasNext() ? iter1.next() : valueForNoneA, iter2.hasNext() ? iter2.next() : valueForNoneB);
}
};
}
};
}
/**
*
* @param
* @param
* @param
* @param iter
* @param unzip output parameter.
* @return
*/
public static BiIterator unzip(final Iterator extends T> iter, final BiConsumer super T, Pair> unzip) {
if (iter == null) {
return BiIterator.empty();
}
final BooleanSupplier hasNext = iter::hasNext;
final Consumer> output = out -> unzip.accept(iter.next(), out);
return BiIterator.generate(hasNext, output);
}
/**
* For each remaining.
*
* @param
* @param action
* @throws E the e
*/
public abstract void forEachRemaining(final Throwables.BiConsumer super A, ? super B, E> action) throws E;
/**
* It's preferred to call forEachRemaining(Try.BiConsumer)
to avoid the create the unnecessary Pair
Objects.
*
* @param action
* @deprecated
*/
@Override
@Deprecated
public void forEachRemaining(java.util.function.Consumer super Pair> action) {
super.forEachRemaining(action);
}
/**
*
* @param
* @param mapper
* @return
*/
public abstract ObjIterator map(final BiFunction super A, ? super B, R> mapper);
/**
*
* @param
* @param mapper
* @return
*/
public Stream stream(final BiFunction super A, ? super B, R> mapper) {
N.checkArgNotNull(mapper);
return Stream.of(map(mapper));
}
public Pair[] toArray() {
return toArray(new Pair[0]);
}
public T[] toArray(final T[] a) {
return toList().toArray(a);
}
public List> toList() {
return toCollection(Suppliers.> ofList());
}
}