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-android Show documentation
Show all versions of abacus-android Show documentation
A general and simple library for Android
/*
* 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.NoSuchElementException;
import com.landawn.abacus.util.function.BiConsumer;
import com.landawn.abacus.util.function.BooleanSupplier;
import com.landawn.abacus.util.function.Consumer;
import com.landawn.abacus.util.function.IndexedConsumer;
import com.landawn.abacus.util.function.TriFunction;
import com.landawn.abacus.util.stream.Stream;
/**
*
* @since 1.2.10
*
* @author Haiyang Li
*/
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(Try.TriConsumer action) throws Exception {
N.checkArgNotNull(action);
}
@Override
public ObjIterator map(TriFunction mapper) {
N.checkArgNotNull(mapper);
return ObjIterator.empty();
}
};
public static TriIterator empty() {
return EMPTY;
}
/**
* Returns an infinite {@code BiIterator}.
*
* @param output transfer the next values.
* @return
*/
public static TriIterator generate(final Consumer> output) {
return generate(BooleanSupplier.TRUE, output);
}
/**
*
* @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() == false) {
throw new NoSuchElementException();
}
output.accept(tmp);
return Triple.of(tmp.left, tmp.middle, tmp.right);
}
@Override
public void forEachRemaining(final Try.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() == false) {
throw new NoSuchElementException();
}
output.accept(tmp);
return mapper.apply(tmp.left, tmp.middle, tmp.right);
}
};
}
};
}
/**
*
* @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() == false) {
throw new NoSuchElementException();
}
output.accept(cursor.getAndIncrement(), tmp);
return Triple.of(tmp.left, tmp.middle, tmp.right);
}
@Override
public void forEachRemaining(final Try.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() == false) {
throw new NoSuchElementException();
}
output.accept(cursor.getAndIncrement(), tmp);
return mapper.apply(tmp.left, tmp.middle, tmp.right);
}
};
}
};
}
public static TriIterator zip(final A[] a, final B[] b, final C[] c) {
return zip(Array.asList(a), Array.asList(b), Array.asList(c));
}
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);
}
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());
}
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);
}
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() == false) {
throw new NoSuchElementException();
}
return Triple.of(iterA.next(), iterB.next(), iterC.next());
}
@Override
public void forEachRemaining(final Try.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() == false) {
throw new NoSuchElementException();
}
return mapper.apply(iterA.next(), iterB.next(), iterC.next());
}
};
}
};
}
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() == false) {
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 Try.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() == false) {
throw new NoSuchElementException();
}
return mapper.apply(iter1.hasNext() ? iter1.next() : valueForNoneA, iter2.hasNext() ? iter2.next() : valueForNoneB,
iter3.hasNext() ? iter3.next() : valueForNoneC);
}
};
}
};
}
/**
*
* @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 = new BooleanSupplier() {
@Override
public boolean getAsBoolean() {
return iter.hasNext();
}
};
final Consumer> output = new Consumer>() {
@Override
public void accept(Triple out) {
unzip.accept(iter.next(), out);
}
};
return TriIterator.generate(hasNext, output);
}
public abstract void forEachRemaining(final Try.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.
*
* @deprecated
*/
@Override
@Deprecated
public void forEachRemaining(java.util.function.Consumer super Triple> action) {
super.forEachRemaining(action);
}
public abstract ObjIterator map(final TriFunction super A, ? super B, ? super C, R> mapper);
public Stream stream(final TriFunction super A, ? super B, ? super C, R> mapper) {
N.checkArgNotNull(mapper);
return Stream.of(map(mapper));
}
}