com.landawn.abacus.util.TriIterator 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.NoSuchElementException;
import java.util.function.BiConsumer;
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.function.TriFunction;
import com.landawn.abacus.util.stream.Stream;
/**
*
* @author Haiyang Li
* @param
* @param
* @param
* @since 1.2.10
*/
public abstract class TriIterator extends ImmutableIterator> {
@SuppressWarnings("rawtypes")
private static final TriIterator EMPTY = new TriIterator() {
@Override
public boolean hasNext() {
return false;
}
@Override
public Object next() {
throw new NoSuchElementException();
}
@Override
public void forEachRemaining(Throwables.TriConsumer action) throws Exception {
N.checkArgNotNull(action);
}
@Override
public ObjIterator map(TriFunction mapper) {
N.checkArgNotNull(mapper);
return ObjIterator.empty();
}
};
/**
*
* @param
* @param
* @param
* @return
*/
public static TriIterator empty() {
return EMPTY;
}
/**
* Returns an infinite {@code BiIterator}.
*
* @param
* @param
* @param
* @param output transfer the next values.
* @return
*/
public static TriIterator generate(final Consumer> output) {
return generate(com.landawn.abacus.util.function.BooleanSupplier.TRUE, output);
}
/**
*
* @param
* @param
* @param
* @param hasNext
* @param output
* @return
*/
public static TriIterator generate(final BooleanSupplier hasNext, final Consumer> output) {
N.checkArgNotNull(hasNext);
N.checkArgNotNull(output);
return new TriIterator<>() {
private final Triple tmp = new Triple<>();
@Override
public boolean hasNext() {
return hasNext.getAsBoolean();
}
@Override
public Triple next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
output.accept(tmp);
return Triple.of(tmp.left, tmp.middle, tmp.right);
}
@Override
public void forEachRemaining(final Throwables.TriConsumer super A, ? super B, ? super C, E> action) throws E {
N.checkArgNotNull(action);
while (hasNext.getAsBoolean()) {
output.accept(tmp);
action.accept(tmp.left, tmp.middle, tmp.right);
}
}
@Override
public ObjIterator map(final TriFunction super A, ? super B, ? super C, 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.middle, tmp.right);
}
};
}
};
}
/**
*
* @param
* @param
* @param
* @param fromIndex
* @param toIndex
* @param output
* @return
*/
public static TriIterator generate(final int fromIndex, final int toIndex, final IndexedConsumer> output) {
N.checkFromToIndex(fromIndex, toIndex, Integer.MAX_VALUE);
N.checkArgNotNull(output);
return new TriIterator<>() {
private final MutableInt cursor = MutableInt.of(fromIndex);
private final Triple tmp = new Triple<>();
@Override
public boolean hasNext() {
return cursor.value() < toIndex;
}
@Override
public Triple next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
output.accept(cursor.getAndIncrement(), tmp);
return Triple.of(tmp.left, tmp.middle, tmp.right);
}
@Override
public void forEachRemaining(final Throwables.TriConsumer super A, ? super B, ? super C, E> action) throws E {
N.checkArgNotNull(action);
while (cursor.value() < toIndex) {
output.accept(cursor.getAndIncrement(), tmp);
action.accept(tmp.left, tmp.middle, tmp.right);
}
}
@Override
public ObjIterator map(final TriFunction super A, ? super B, ? super C, 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.middle, tmp.right);
}
};
}
};
}
/**
*
* @param
* @param
* @param
* @param a
* @param b
* @param c
* @return
*/
public static TriIterator zip(final A[] a, final B[] b, final C[] c) {
return zip(Array.asList(a), Array.asList(b), Array.asList(c));
}
/**
*
* @param
* @param
* @param
* @param a
* @param b
* @param c
* @param valueForNoneA
* @param valueForNoneB
* @param valueForNoneC
* @return
*/
public static TriIterator zip(final A[] a, final B[] b, final C[] c, final A valueForNoneA, final B valueForNoneB,
final C valueForNoneC) {
return zip(Array.asList(a), Array.asList(b), Array.asList(c), valueForNoneA, valueForNoneB, valueForNoneC);
}
/**
*
* @param
* @param
* @param
* @param a
* @param b
* @param c
* @return
*/
public static TriIterator zip(final Collection a, final Collection b, final Collection c) {
return zip(a == null ? null : a.iterator(), b == null ? null : b.iterator(), c == null ? null : c.iterator());
}
/**
*
* @param
* @param
* @param
* @param a
* @param b
* @param c
* @param valueForNoneA
* @param valueForNoneB
* @param valueForNoneC
* @return
*/
public static TriIterator zip(final Collection a, final Collection b, final Collection c, final A valueForNoneA,
final B valueForNoneB, final C valueForNoneC) {
return zip(a == null ? null : a.iterator(), b == null ? null : b.iterator(), c == null ? null : c.iterator(), valueForNoneA, valueForNoneB,
valueForNoneC);
}
/**
*
* @param
* @param
* @param
* @param iterA
* @param iterB
* @param iterC
* @return
*/
public static TriIterator zip(final Iterator iterA, final Iterator iterB, final Iterator iterC) {
if (iterA == null || iterB == null || iterC == null) {
return empty();
}
return new TriIterator<>() {
@Override
public boolean hasNext() {
return iterA.hasNext() && iterB.hasNext() && iterC.hasNext();
}
@Override
public Triple next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return Triple.of(iterA.next(), iterB.next(), iterC.next());
}
@Override
public void forEachRemaining(final Throwables.TriConsumer super A, ? super B, ? super C, E> action) throws E {
N.checkArgNotNull(action);
while (iterA.hasNext() && iterB.hasNext() && iterC.hasNext()) {
action.accept(iterA.next(), iterB.next(), iterC.next());
}
}
@Override
public ObjIterator map(final TriFunction super A, ? super B, ? super C, R> mapper) {
N.checkArgNotNull(mapper);
return new ObjIterator<>() {
@Override
public boolean hasNext() {
return iterA.hasNext() && iterB.hasNext() && iterC.hasNext();
}
@Override
public R next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return mapper.apply(iterA.next(), iterB.next(), iterC.next());
}
};
}
};
}
/**
*
* @param
* @param
* @param
* @param iterA
* @param iterB
* @param iterC
* @param valueForNoneA
* @param valueForNoneB
* @param valueForNoneC
* @return
*/
public static TriIterator zip(final Iterator iterA, final Iterator iterB, final Iterator iterC, final A valueForNoneA,
final B valueForNoneB, final C valueForNoneC) {
final Iterator iter1 = iterA == null ? ObjIterator. empty() : iterA;
final Iterator iter2 = iterB == null ? ObjIterator. empty() : iterB;
final Iterator iter3 = iterC == null ? ObjIterator. empty() : iterC;
return new TriIterator<>() {
@Override
public boolean hasNext() {
return iter1.hasNext() || iter2.hasNext() || iter3.hasNext();
}
@Override
public Triple next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return Triple.of(iter1.hasNext() ? iter1.next() : valueForNoneA, iter2.hasNext() ? iter2.next() : valueForNoneB,
iter3.hasNext() ? iter3.next() : valueForNoneC);
}
@Override
public void forEachRemaining(final Throwables.TriConsumer super A, ? super B, ? super C, E> action) throws E {
N.checkArgNotNull(action);
while (iter1.hasNext() || iter2.hasNext() || iter3.hasNext()) {
action.accept(iter1.hasNext() ? iter1.next() : valueForNoneA, iter2.hasNext() ? iter2.next() : valueForNoneB,
iter3.hasNext() ? iter3.next() : valueForNoneC);
}
}
@Override
public ObjIterator map(final TriFunction super A, ? super B, ? super C, R> mapper) {
N.checkArgNotNull(mapper);
return new ObjIterator<>() {
@Override
public boolean hasNext() {
return iter1.hasNext() || iter2.hasNext() || iter3.hasNext();
}
@Override
public R next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return mapper.apply(iter1.hasNext() ? iter1.next() : valueForNoneA, iter2.hasNext() ? iter2.next() : valueForNoneB,
iter3.hasNext() ? iter3.next() : valueForNoneC);
}
};
}
};
}
/**
*
* @param
* @param
* @param
* @param
* @param iter
* @param unzip output parameter.
* @return
*/
public static TriIterator unzip(final Iterator extends T> iter, final BiConsumer super T, Triple> unzip) {
if (iter == null) {
return TriIterator.empty();
}
final BooleanSupplier hasNext = iter::hasNext;
final Consumer> output = out -> unzip.accept(iter.next(), out);
return TriIterator.generate(hasNext, output);
}
/**
* For each remaining.
*
* @param
* @param action
* @throws E the e
*/
public abstract void forEachRemaining(final Throwables.TriConsumer super A, ? super B, ? super C, E> action) throws E;
/**
* It's preferred to call forEachRemaining(Try.TriConsumer)
to avoid the create the unnecessary Triple
Objects.
*
* @param action
* @deprecated
*/
@Override
@Deprecated
public void forEachRemaining(java.util.function.Consumer super Triple> action) {
super.forEachRemaining(action);
}
/**
*
* @param
* @param mapper
* @return
*/
public abstract ObjIterator map(final TriFunction super A, ? super B, ? super C, R> mapper);
/**
*
* @param
* @param mapper
* @return
*/
public Stream stream(final TriFunction super A, ? super B, ? super C, R> mapper) {
N.checkArgNotNull(mapper);
return Stream.of(map(mapper));
}
public Triple[] toArray() {
return toArray(new Triple[0]);
}
public T[] toArray(final T[] a) {
return toList().toArray(a);
}
public List> toList() {
return toCollection(Suppliers.ofList());
}
}