
com.landawn.abacus.util.ObjIterator 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.
The newest version!
/*
* Copyright (c) 2017, 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
*
* https://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.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.BooleanSupplier;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import com.landawn.abacus.annotation.Beta;
import com.landawn.abacus.util.u.Nullable;
import com.landawn.abacus.util.stream.Stream;
/**
*
* @see ObjListIterator
* @see com.landawn.abacus.util.Iterators
* @see com.landawn.abacus.util.Enumerations
* @see Throwables.Iterator
* @param
*/
@SuppressWarnings({ "java:S6548" })
public abstract class ObjIterator extends ImmutableIterator {
@SuppressWarnings("rawtypes")
private static final ObjIterator EMPTY = new ObjIterator() {
@Override
public boolean hasNext() {
return false;
}
@Override
public Object next() {
throw new NoSuchElementException(InternalUtil.ERROR_MSG_FOR_NO_SUCH_EX);
}
@Override
public ObjIterator skipNulls() {
return this;
}
};
/**
* Returns an empty ObjIterator instance.
*
* @return an ObjIterator with no elements
*/
public static ObjIterator empty() {
return EMPTY;
}
/**
* Returns an ObjIterator with a single element.
*
* @param The type of the element in the iterator.
* @param val The single value to be iterated.
* @return An ObjIterator with a single element.
*/
public static ObjIterator just(final T val) {
return new ObjIterator<>() {
private boolean done = false;
@Override
public boolean hasNext() {
return !done;
}
@Override
public T next() {
if (done) {
throw new NoSuchElementException(InternalUtil.ERROR_MSG_FOR_NO_SUCH_EX);
}
done = true;
return val;
}
};
}
/**
* Returns an ObjIterator for the given array.
*
* @param The type of the elements in the array.
* @param a The array to be iterated.
* @return An ObjIterator for the given array.
*/
@SafeVarargs
public static ObjIterator of(final T... a) {
return N.isEmpty(a) ? EMPTY : of(a, 0, a.length);
}
/**
* Returns an ObjIterator for the given array, starting from the specified index and ending at the specified index.
*
* @param The type of the elements in the array.
* @param a The array to be iterated.
* @param fromIndex The index to start the iteration from.
* @param toIndex The index to end the iteration at.
* @return An ObjIterator for the given array starting from the specified index and ending at the specified index.
* @throws IndexOutOfBoundsException If fromIndex is negative, toIndex is greater than the length of the array, or fromIndex is greater than toIndex.
*/
public static ObjIterator of(final T[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException {
N.checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length);
if (N.isEmpty(a) || fromIndex == toIndex) {
return EMPTY;
}
return new ObjIterator<>() {
private int cursor = fromIndex;
@Override
public boolean hasNext() {
return cursor < toIndex;
}
@Override
public T next() {
if (cursor >= toIndex) {
throw new NoSuchElementException(InternalUtil.ERROR_MSG_FOR_NO_SUCH_EX);
}
return a[cursor++];
}
@Override
public A[] toArray(A[] output) {
if (output.length < toIndex - cursor) {
output = N.copyOf(output, toIndex - cursor);
}
N.copy(a, cursor, output, 0, toIndex - cursor);
return output;
}
@Override
public List toList() {
return N.asList((T[]) toArray());
}
};
}
/**
* Returns an ObjIterator(wrapper) for the given Iterator. If the Iterator is {@code null}, returns an empty ObjIterator.
*
* @param The type of the elements in the iterator.
* @param iter The Iterator to be converted into an ObjIterator.
* @return An ObjIterator for the given Iterator.
*/
public static ObjIterator of(final Iterator extends T> iter) {
if (iter == null) {
return empty();
} else if (iter instanceof ObjIterator) {
return (ObjIterator) iter;
}
return new ObjIterator<>() {
@Override
public boolean hasNext() {
return iter.hasNext();
}
@Override
public T next() {
return iter.next();
}
};
}
/**
* Returns an ObjIterator for the given Collection. If the Collection is empty, returns an empty ObjIterator.
*
* @param The type of the elements in the collection.
* @param iterable The Collection to be converted into an ObjIterator.
* @return An ObjIterator for the given Collection.
*/
public static ObjIterator of(final Collection extends T> iterable) {
return iterable == null ? ObjIterator.empty() : of(iterable.iterator());
}
/**
* Returns an ObjIterator for the given Iterable. If the Iterable is {@code null}, returns an empty ObjIterator.
*
* @param The type of the elements in the iterable.
* @param iterable The Iterable to be converted into an ObjIterator.
* @return An ObjIterator for the given Iterable.
*/
public static ObjIterator of(final Iterable extends T> iterable) {
return iterable == null ? ObjIterator.empty() : of(iterable.iterator());
}
/**
* Returns an ObjIterator instance created lazily using the provided Supplier.
* The Supplier is responsible for producing the ObjIterator instance when the first method in the returned {@code ObjIterator} is called.
*
* @param the type of elements returned by this iterator
* @param iteratorSupplier A Supplier that produces an Iterator instance when called.
* @return An ObjIterator that uses the provided Supplier to generate its Iterator instance.
* @throws IllegalArgumentException If iteratorSupplier is {@code null}.
*/
public static ObjIterator defer(final Supplier extends Iterator extends T>> iteratorSupplier) throws IllegalArgumentException {
N.checkArgNotNull(iteratorSupplier, cs.iteratorSupplier);
return new ObjIterator<>() {
private Iterator extends T> iter = null;
private boolean isInitialized = false;
@Override
public boolean hasNext() {
if (!isInitialized) {
init();
}
return iter.hasNext();
}
@Override
public T next() {
if (!isInitialized) {
init();
}
return iter.next();
}
private void init() {
if (!isInitialized) {
isInitialized = true;
iter = iteratorSupplier.get();
}
}
};
}
/**
* Generates an infinite {@code ObjIterator} instance with the provided supplier.
* The supplier is responsible for producing the next element on each iteration.
*
* @param the type of elements returned by this iterator
* @param supplier A Supplier that produces the next element on each iteration.
* @return An ObjIterator that uses the provided supplier to generate its elements.
* @throws IllegalArgumentException If supplier is {@code null}.
* @see ObjIterator#generate(BooleanSupplier, Supplier)
*/
public static ObjIterator generate(final Supplier extends T> supplier) throws IllegalArgumentException {
N.checkArgNotNull(supplier);
return new ObjIterator<>() {
@Override
public boolean hasNext() {
return true;
}
@Override
public T next() { // NOSONAR
return supplier.get();
}
};
}
/**
* Generates an ObjIterator instance with the provided hasNext BooleanSupplier and supplier.
* The hasNext BooleanSupplier is used to determine if the iterator has more elements.
* The supplier is responsible for producing the next element on each iteration.
*
* @param the type of elements returned by this iterator
* @param hasNext A BooleanSupplier that returns {@code true} if the iterator has more elements.
* @param supplier A Supplier that produces the next element on each iteration.
* @return An ObjIterator that uses the provided hasNext BooleanSupplier and supplier to generate its elements.
* @throws IllegalArgumentException If hasNext or supplier is {@code null}.
*/
public static ObjIterator generate(final BooleanSupplier hasNext, final Supplier extends T> supplier) throws IllegalArgumentException {
N.checkArgNotNull(hasNext);
N.checkArgNotNull(supplier);
return new ObjIterator<>() {
@Override
public boolean hasNext() {
return hasNext.getAsBoolean();
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException(InternalUtil.ERROR_MSG_FOR_NO_SUCH_EX);
}
return supplier.get();
}
};
}
// /**
// * Returns a new {@code ObjIterator}.
// *
// * @param n
// * @return
// * @see Iterators#skip(Iterator, long)
// */
// public ObjIterator skip(final long n) {
// return Iterators.skip(this, n);
// }
//
// /**
// * Returns a new {@code ObjIterator}.
// *
// * @param count
// * @return
// * @see Iterators#limit(Iterator, long)
// */
// public ObjIterator limit(final long count) {
// return Iterators.limit(this, count);
// }
//
// /**
// * Returns a new {@code ObjIterator}.
// *
// * @param offset
// * @param count
// * @return
// * @see Iterators#skipAndLimit(Iterator, long, long)
// */
// public ObjIterator skipAndLimit(final long offset, final long count) {
// return Iterators.skipAndLimit(this, offset, count);
// }
//
// /**
// * Returns a new {@code ObjIterator}.
// *
// * @param filter
// * @return
// * @see Iterators#filter(Iterator, Predicate)
// */
// public ObjIterator filter(final Predicate super T> filter) {
// return Iterators.filter(this, filter);
// }
//
// /**
// * Returns a new {@code ObjIterator}.
// *
// * @param filter
// * @return
// * @see Iterators#takeWhile(Iterator, Predicate)
// */
// public ObjIterator takeWhile(final Predicate super T> filter) {
// return Iterators.takeWhile(this, filter);
// }
//
// /**
// * Returns a new {@code ObjIterator}.
// *
// * @param filter
// * @return
// * @see Iterators#takeWhileInclusive(Iterator, Predicate)
// */
// public ObjIterator takeWhileInclusive(final Predicate super T> filter) {
// return Iterators.takeWhileInclusive(this, filter);
// }
//
// /**
// * Returns a new {@code ObjIterator}.
// *
// * @param filter
// * @return
// * @see Iterators#dropWhile(Iterator, Predicate)
// */
// public ObjIterator dropWhile(final Predicate super T> filter) {
// return Iterators.dropWhile(this, filter);
// }
//
// /**
// * Returns a new {@code ObjIterator}.
// *
// * @param filter
// * @return
// * @see Iterators#skipUntil(Iterator, Predicate)
// */
// public ObjIterator skipUntil(final Predicate super T> filter) {
// return Iterators.skipUntil(this, filter);
// }
//
// /**
// * Returns a new {@code ObjIterator}.
// *
// * @param
// * @param mapper
// * @return
// * @see Iterators#map(Iterator, Function)
// */
// public ObjIterator map(final Function super T, U> mapper) {
// return Iterators.map(this, mapper);
// }
//
// /**
// * Returns a new {@code ObjIterator}.
// *
// * @param
// * @param mapper
// * @return
// * @see Iterators#flatMap(Iterator, Function)
// */
// public ObjIterator flatMap(final Function super T, ? extends Collection extends U>> mapper) {
// return Iterators.flatMap(this, mapper);
// }
//
// /**
// * Returns a new {@code ObjIterator}.
// *
// * @param
// * @param mapper
// * @return
// * @see Iterators#flatmap(Iterator, Function)
// */
// public ObjIterator flatmap(final Function super T, ? extends U[]> mapper) {
// return Iterators.flatmap(this, mapper);
// }
/**
* Generates an ObjIterator instance with the provided initial value, hasNext Predicate, and supplier.
* The hasNext Predicate is used to determine if the iterator has more elements.
* The supplier is responsible for producing the next element on each iteration.
*
* @param the type of elements returned by this iterator
* @param the type of the initial value
* @param init The value for the first call from hasNext and supplier> functions.
* @param hasNext A Predicate that accepts an instance of U and returns {@code true} if the iterator has more elements.
* @param supplier A Function that accepts an instance of U and produces the next element on each iteration.
* @return An ObjIterator that uses the provided initial value, hasNext Predicate, and supplier to generate its elements.
* @throws IllegalArgumentException If hasNext or supplier is {@code null}.
*/
public static ObjIterator generate(final U init, final Predicate super U> hasNext, final Function super U, T> supplier)
throws IllegalArgumentException {
N.checkArgNotNull(hasNext);
N.checkArgNotNull(supplier);
return new ObjIterator<>() {
@Override
public boolean hasNext() {
return hasNext.test(init);
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return supplier.apply(init);
}
};
}
/**
* Generates an ObjIterator instance with the provided initial value, hasNext BiPredicate, and supplier.
* The hasNext BiPredicate is used to determine if the iterator has more elements.
* The supplier is responsible for producing the next element on each iteration.
*
* @param the type of elements returned by this iterator
* @param the type of the initial value
* @param init The value for the first call from hasNext and supplier> functions.
* @param hasNext A BiPredicate that accepts an instance of U and T and returns {@code true} if the iterator has more elements.
* @param supplier A BiFunction that accepts an instance of U and T and produces the next element on each iteration.
* @return An ObjIterator that uses the provided initial value, hasNext BiPredicate, and supplier to generate its elements.
* @throws IllegalArgumentException If hasNext or supplier is {@code null}.
*/
public static ObjIterator generate(final U init, final BiPredicate super U, T> hasNext, final BiFunction super U, T, T> supplier)
throws IllegalArgumentException {
N.checkArgNotNull(hasNext);
N.checkArgNotNull(supplier);
return new ObjIterator<>() {
private T prev = null;
@Override
public boolean hasNext() {
return hasNext.test(init, prev);
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return (prev = supplier.apply(init, prev));
}
};
}
/**
* Returns a new ObjIterator with n elements skipped from the beginning of this iterator.
*
* @param n The number of elements to skip.
* @return A new ObjIterator that skips the first n elements.
* @throws IllegalArgumentException If n is negative.
*/
public ObjIterator skip(final long n) throws IllegalArgumentException {
N.checkArgNotNegative(n, cs.n);
if (n <= 0) {
return this;
}
final ObjIterator iter = this;
return new ObjIterator<>() {
private boolean skipped = false;
@Override
public boolean hasNext() {
if (!skipped) {
skip();
}
return iter.hasNext();
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException(InternalUtil.ERROR_MSG_FOR_NO_SUCH_EX);
}
return iter.next();
}
private void skip() {
long idx = 0;
while (idx++ < n && iter.hasNext()) {
iter.next();
}
skipped = true;
}
};
}
/**
* Returns a new ObjIterator with count elements from the beginning of this iterator.
*
* @param count The number of elements to limit.
* @return A new ObjIterator that includes the first count elements.
* @throws IllegalArgumentException If count is negative.
*/
public ObjIterator limit(final long count) throws IllegalArgumentException {
N.checkArgNotNegative(count, cs.count);
if (count == 0) {
return ObjIterator.empty();
}
final ObjIterator iter = this;
return new ObjIterator<>() {
private long cnt = count;
@Override
public boolean hasNext() {
return cnt > 0 && iter.hasNext();
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException(InternalUtil.ERROR_MSG_FOR_NO_SUCH_EX);
}
cnt--;
return iter.next();
}
};
}
/**
* Returns a new ObjIterator that skips the first offset elements and includes the next count elements.
*
* @param offset The number of elements to skip from the beginning of this iterator.
* @param count The number of elements to include after skipping.
* @return A new ObjIterator that skips the first offset elements and includes the next count elements.
* @throws IllegalArgumentException If offset or count is negative.
*/
public ObjIterator skipAndLimit(final long offset, final long count) {
return Iterators.skipAndLimit(this, offset, count);
}
/**
* Returns a new ObjIterator that includes only the elements that satisfy the provided predicate.
*
* @param predicate The Predicate to apply to each element.
* @return A new ObjIterator that includes only the elements that satisfy the provided predicate.
*/
public ObjIterator filter(final Predicate super T> predicate) {
return Iterators.filter(this, predicate);
}
/**
* Transforms the elements in this ObjIterator by applying the provided mapping function.
*
* @param The type of the elements in the resulting ObjIterator.
* @param mapper The function to apply to each element in this ObjIterator.
* @return A new ObjIterator that includes the transformed elements.
*/
@Beta
public ObjIterator map(final Function super T, U> mapper) {
return Iterators.map(this, mapper);
}
/**
* Returns a new ObjIterator with distinct elements based on their natural equality.
*
* @return
*/
public ObjIterator distinct() {
final Set elements = new HashSet<>();
return filter(elements::add);
}
/**
* Returns a new ObjIterator with distinct elements based on the keyExtractor.
* The keyExtractor is used to extract the key for each element, and the key is used to determine the uniqueness of the element.
* If the keyExtractor returns the same key for multiple elements, only the first element with that key is included in the resulting ObjIterator.
* @param keyExtractor
* @return
*/
public ObjIterator distinctBy(final Function super T, ?> keyExtractor) {
final Set
© 2015 - 2025 Weber Informatics LLC | Privacy Policy