com.landawn.abacus.util.Seq 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) 2019 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.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Serial;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.security.SecureRandom;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Deque;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NoSuchElementException;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.function.ToDoubleFunction;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
import java.util.regex.Pattern;
import java.util.stream.Collector;
import com.landawn.abacus.annotation.Beta;
import com.landawn.abacus.annotation.IntermediateOp;
import com.landawn.abacus.annotation.Internal;
import com.landawn.abacus.annotation.LazyEvaluation;
import com.landawn.abacus.annotation.SequentialOnly;
import com.landawn.abacus.annotation.SuppressFBWarnings;
import com.landawn.abacus.annotation.TerminalOp;
import com.landawn.abacus.annotation.TerminalOpTriggered;
import com.landawn.abacus.exception.TooManyElementsException;
import com.landawn.abacus.exception.UncheckedIOException;
import com.landawn.abacus.logging.Logger;
import com.landawn.abacus.logging.LoggerFactory;
import com.landawn.abacus.parser.JSONParser;
import com.landawn.abacus.parser.JSONSerializationConfig;
import com.landawn.abacus.parser.JSONSerializationConfig.JSC;
import com.landawn.abacus.parser.ParserFactory;
import com.landawn.abacus.parser.ParserUtil;
import com.landawn.abacus.parser.ParserUtil.BeanInfo;
import com.landawn.abacus.parser.ParserUtil.PropInfo;
import com.landawn.abacus.type.Type;
import com.landawn.abacus.util.Fn.Factory;
import com.landawn.abacus.util.Fn.Fnn;
import com.landawn.abacus.util.Fn.Suppliers;
import com.landawn.abacus.util.If.OrElse;
import com.landawn.abacus.util.u.Optional;
import com.landawn.abacus.util.u.OptionalDouble;
import com.landawn.abacus.util.u.OptionalInt;
import com.landawn.abacus.util.u.OptionalLong;
import com.landawn.abacus.util.function.IntBiFunction;
import com.landawn.abacus.util.function.TriFunction;
import com.landawn.abacus.util.stream.Collectors;
import com.landawn.abacus.util.stream.IntStream;
import com.landawn.abacus.util.stream.ObjIteratorEx;
import com.landawn.abacus.util.stream.Stream;
/**
* The sequence class is an abstract class that represents a sequence of elements and supports different kinds of computations.
* The sequence operations are divided into intermediate and terminal operations, and are combined to form sequence pipelines.
*
* The sequence will be automatically closed after a terminal method is called/triggered
*
* {@code Seq} can be easily transformed to {@code Stream} by the {@code transformB} methods
* Refer to {@code com.landawn.abacus.util.stream.BaseStream} and {@code com.landawn.abacus.util.stream.Stream} for more APIs docs.
*
* @param the type of the elements in this stream
* @param the type of the checked exception this sequence can throw
*
* @see com.landawn.abacus.util.stream.BaseStream
* @see com.landawn.abacus.util.stream.EntryStream
* @see com.landawn.abacus.util.stream.IntStream
* @see com.landawn.abacus.util.stream.LongStream
* @see com.landawn.abacus.util.stream.DoubleStream
* @see com.landawn.abacus.util.stream.Collectors
* @see com.landawn.abacus.util.Fn
* @see com.landawn.abacus.util.Comparators
* @see com.landawn.abacus.util.ExceptionUtil
* @see java.util.stream.Stream
*
*/
@Beta
@LazyEvaluation
@SequentialOnly
@com.landawn.abacus.annotation.Immutable
@SuppressWarnings({ "java:S1192", "java:S1698", "java:S4968", "java:S6539" })
public final class Seq implements AutoCloseable, Immutable {
// There are a lot of methods commented out by purpose, because they are not necessary or not recommended to be used in Seq.
// Additionally, a lot of methods defined Stream but not here can be supported through methods: transformB, sps, etc.
// If you really need them, please use Stream instead.
// BE CAUTION ON UN-COMMENTING THEM.
// Please refer to the latest implementation/doc in Stream for any un-commended methods.
// Tested performance with below code. It seems there is no meaningful performance improvement brought by Seq, comparing with Stream.
// Remove the Seq for now???
// @Test
// public void test_try_catch_perf() {
// final int len = 1000_000;
// final int loopNum = 100;
//
// Profiler.run(1, loopNum, 3, "noTryCatch", () -> {
// final long count = Stream.range(0, len).map(it -> notThrowSQLException()).count();
//
// assertEquals(len, count);
// }).printResult();
//
// Profiler.run(1, loopNum, 3, "cmdWithTryCatch", () -> {
// final long count = Stream.range(0, len).map(Fn.ff(it -> maybeThrowSQLException())).count();
//
// assertEquals(len, count);
// }).printResult();
//
// Profiler.run(1, loopNum, 3, "cmdBySeq", () -> {
// try {
// final long count = Seq. range(0, len).map(it -> maybeThrowSQLException()).count();
// assertEquals(len, count);
// } catch (final SQLException e) {
// throw ExceptionUtil.toRuntimeException(e, true);
// }
// }).printResult();
//
// }
//
// @SuppressWarnings("unused")
// String maybeThrowSQLException() throws SQLException {
// return "abc"; // Strings.uuid();
// }
//
// String notThrowSQLException() {
// return "abc"; // Strings.uuid();
// }
private static final Logger logger = LoggerFactory.getLogger(Seq.class);
private static final int BATCH_SIZE_FOR_FLUSH = 200;
private static final Throwables.Function GET_AS_INT = OptionalInt::get;
private static final Throwables.Function GET_AS_LONG = OptionalLong::get;
private static final Throwables.Function GET_AS_DOUBLE = OptionalDouble::get;
@SuppressWarnings("rawtypes")
private static final Throwables.Function GET_AS_IT = it -> it.orElse(null);
// @SuppressWarnings("rawtypes")
// private static final Throwables.Function GET_AS_IT_JDK = it -> it.orElse(null);
private static final Throwables.Predicate IS_PRESENT_INT = OptionalInt::isPresent;
private static final Throwables.Predicate IS_PRESENT_LONG = OptionalLong::isPresent;
private static final Throwables.Predicate IS_PRESENT_DOUBLE = OptionalDouble::isPresent;
@SuppressWarnings("rawtypes")
private static final Throwables.Predicate IS_PRESENT_IT = Optional::isPresent;
// private static final Throwables.Function, Object>, Object, Exception> KK = t -> t.getKey().val();
private static final Object NONE = ClassUtil.createNullMask();
private static final Random RAND = new SecureRandom();
private static final String ERROR_MSG_FOR_NO_SUCH_EX = InternalUtil.ERROR_MSG_FOR_NO_SUCH_EX;
/**
*
* Char array with value {@code "['n', 'u', 'l', 'l']"}.
*/
private static final char[] NULL_CHAR_ARRAY = Strings.NULL_STRING.toCharArray();
private static final char[] ELEMENT_SEPARATOR_CHAR_ARRAY = Strings.ELEMENT_SEPARATOR.toCharArray();
private static final int MAX_WAIT_TIME_FOR_QUEUE_OFFER = 9; // unit is milliseconds
private static final int MAX_WAIT_TIME_FOR_QUEUE_POLL = 7; // unit is milliseconds
static final int MAX_WAIT_TIME_FOR_QUEUE_OFFER_FOR_ADD_SUBSCRIBER = 30_000; // unit is milliseconds
private static final int DEFAULT_BUFFERED_SIZE_PER_ITERATOR = 64;
@SuppressWarnings("rawtypes")
private static final Comparator NATURAL_COMPARATOR = Comparators.naturalOrder();
@SuppressWarnings("rawtypes")
private static final Comparator REVERSED_COMPARATOR = Comparators.reverseOrder();
private static final Comparator CHAR_COMPARATOR = Character::compare;
private static final Comparator BYTE_COMPARATOR = Byte::compare;
private static final Comparator SHORT_COMPARATOR = Short::compare;
private static final Comparator INT_COMPARATOR = Integer::compare;
private static final Comparator LONG_COMPARATOR = Long::compare;
private static final Comparator FLOAT_COMPARATOR = Float::compare;
private static final Comparator DOUBLE_COMPARATOR = Double::compare;
private static final BiMap, Comparator>> DEFAULT_COMPARATOR_MAP = new BiMap<>();
static {
DEFAULT_COMPARATOR_MAP.put(char.class, CHAR_COMPARATOR);
DEFAULT_COMPARATOR_MAP.put(byte.class, BYTE_COMPARATOR);
DEFAULT_COMPARATOR_MAP.put(short.class, SHORT_COMPARATOR);
DEFAULT_COMPARATOR_MAP.put(int.class, INT_COMPARATOR);
DEFAULT_COMPARATOR_MAP.put(long.class, LONG_COMPARATOR);
DEFAULT_COMPARATOR_MAP.put(float.class, FLOAT_COMPARATOR);
DEFAULT_COMPARATOR_MAP.put(double.class, DOUBLE_COMPARATOR);
DEFAULT_COMPARATOR_MAP.put(Object.class, NATURAL_COMPARATOR);
}
private static final LocalRunnable EMPTY_CLOSE_HANDLER = () -> {
// do nothing.
};
private final Throwables.Iterator elements;
private final boolean sorted;
private final Comparator super T> cmp;
private final Deque closeHandlers;
private boolean isClosed = false;
Seq(final Throwables.Iterator extends T, ? extends E> iter) {
this(iter, false, null, null);
}
Seq(final Throwables.Iterator extends T, ? extends E> iter, final Collection closeHandlers) {
this(iter, false, null, closeHandlers);
}
Seq(final Throwables.Iterator extends T, ? extends E> iter, final boolean sorted, final Comparator super T> cmp,
final Collection closeHandlers) {
elements = (Throwables.Iterator) iter;
this.sorted = sorted;
this.cmp = cmp;
this.closeHandlers = isEmptyCloseHandlers(closeHandlers) ? null
: (closeHandlers instanceof LocalArrayDeque ? (LocalArrayDeque) closeHandlers : new LocalArrayDeque<>(closeHandlers));
}
// @SuppressWarnings("rawtypes")
// private static final Seq EMPTY_SEQ = new Seq(Throwables.Iterator.empty());
/**
* Returns an empty sequence.
*
* @param the type of the sequence elements
* @param the type of the exception that the sequence can throw
* @return an empty sequence
*/
public static Seq empty() {
return new Seq<>(Throwables.Iterator.empty());
}
// /**
// * Creates a Seq from a given Stream.
// *
// * @param the type of elements in the stream
// * @param the type of exception that might be thrown
// * @param stream where the returned Seq will load elements from.
// * @return a Seq containing the elements of the provided Stream
// */
// public static Seq from(final Stream extends T> stream) {
// return create(stream, false);
// }
//
// /**
// * Creates a Seq from a given Stream.
// *
// * @param the type of elements in the stream
// * @param the type of exception that might be thrown
// * @param stream where the returned Seq will load elements from.
// * @return a Seq containing the elements of the provided Stream
// */
// public static Seq from(final java.util.stream.Stream extends T> stream) {
// if (stream == null) {
// return empty();
// }
//
// return Seq. of(stream.iterator()).onClose(stream::close);
// }
//
// /**
// * Creates a Seq from a given Stream.
// *
// * @param the type of elements in the stream
// * @param the type of exception that might be thrown
// * @param stream where the returned Seq will load elements from.
// * @param exceptionType the type of exception that might be thrown
// * @return a Seq containing the elements of the provided Stream
// */
// // Should the name be from?
// public static Seq from(final Stream extends T> stream,
// @SuppressWarnings("unused") final Class exceptionType) { //NOSONAR
// return from(stream);
// }
//
// /**
// * Creates a Seq from a given Stream.
// *
// * @param the type of elements in the stream
// * @param the type of exception that might be thrown
// * @param stream where the returned Seq will load elements from.
// * @param exceptionType the type of exception that might be thrown
// * @return a Seq containing the elements of the provided Stream
// */
// // Should the name be from?
// public static Seq from(final java.util.stream.Stream extends T> stream,
// @SuppressWarnings("unused") final Class exceptionType) { //NOSONAR
// return from(stream);
// }
// /**
// * Creates a Seq from a given Stream.
// *
// * @param the type of elements in the stream
// * @param the type of exception that might be thrown
// * @param stream the Stream from which the Seq will be created
// * @return a Seq containing the elements of the provided Stream
// * @deprecated Use {@link #from(Stream)} instead
// * @see #from(Stream)
// */
// @Deprecated
// public static Seq of(final Stream extends T> stream) {
// return from(stream);
// }
//
// /**
// * Creates a Seq from a given Stream.
// *
// * @param the type of elements in the stream
// * @param the type of exception that might be thrown
// * @param stream the Stream from which the Seq will be created
// * @return a Seq containing the elements of the provided Stream
// * @deprecated Use {@link #from(java.util.stream.Stream)} instead
// * @see #from(java.util.stream.Stream)
// */
// @Deprecated
// public static Seq of(final java.util.stream.Stream extends T> stream) {
// return from(stream);
// }
//
// /**
// * Creates a Seq from the provided Stream.
// *
// * @param the type of elements in the stream
// * @param the type of exception that might be thrown
// * @param stream the Stream from which the Seq will be created
// * @param exceptionType the type of exception that might be thrown (not used)
// * @return a Seq containing the elements of the provided Stream
// * @deprecated Use {@link #from(Stream, Class)} instead
// * @see #from(Stream, Class)
// */
// // Should the name be from?
// @Deprecated
// public static Seq of(final Stream extends T> stream, @SuppressWarnings("unused") final Class exceptionType) {
// return from(stream, exceptionType);
// }
//
// /**
// * Creates a Seq from a given java.util.stream.Stream.
// *
// * @param the type of elements in the stream
// * @param the type of exception that might be thrown
// * @param stream the java.util.stream.Stream from which the Seq will be created
// * @param exceptionType the type of exception that might be thrown (not used)
// * @return a Seq containing the elements of the provided java.util.stream.Stream
// * @deprecated Use {@link #from(java.util.stream.Stream, Class)} instead
// * @see #from(java.util.stream.Stream, Class)
// */
// // Should the name be from?
// @Deprecated
// public static Seq of(final java.util.stream.Stream extends T> stream,
// @SuppressWarnings("unused") final Class exceptionType) {
// return from(stream, exceptionType);
// }
/**
* Returns a sequence that is lazily populated by an input supplier.
*
*
* @implNote
* This is equal to: {@code Seq.just(supplier).flatMap(Throwables.Supplier::get)}.
*
* @param the type of the sequence elements
* @param the type of the exception that the sequence can throw
* @param supplier the supplier to generate the sequence
* @return a sequence generated by the supplier
* @throws IllegalArgumentException if the supplier is null
*/
public static Seq defer(final Throwables.Supplier extends Seq extends T, ? extends E>, ? extends E> supplier)
throws IllegalArgumentException {
N.checkArgNotNull(supplier, cs.supplier);
//noinspection resource
return Seq., ? extends E>, E> just(supplier).flatMap(Throwables.Supplier::get);
}
/**
* Creates a sequence containing a single element.
*
* @param the type of the element
* @param the type of exception that might be thrown
* @param e the element to be included in the sequence
* @return a sequence containing the provided element
*/
public static Seq just(final T e) {
return of(e);
}
/**
* Creates a sequence containing a single element.
*
* @param the type of the element
* @param the type of exception that might be thrown
* @param e the element to be included in the sequence
* @param exceptionType the type of exception that might be thrown
* @return a sequence containing the provided element
*/
public static Seq just(final T e, @SuppressWarnings("unused") final Class exceptionType) { //NOSONAR
return of(e);
}
/**
* Returns an empty sequence if the specified element is {@code null}, otherwise returns a sequence containing the single specified element.
*
* @param the type of the element
* @param the type of exception that might be thrown
* @param e the element to be included in the sequence if not null
* @return a sequence containing the provided element if not {@code null}, otherwise an empty sequence
*/
public static Seq ofNullable(final T e) {
if (e == null) {
return empty();
}
return of(e);
}
/**
* Returns an empty sequence if the specified element is {@code null}, otherwise returns a sequence containing the single specified element.
*
* @param the type of the element
* @param the type of exception that might be thrown
* @param e the element to be included in the sequence if not null
* @param exceptionType the type of exception that might be thrown
* @return a sequence containing the provided element if not {@code null}, otherwise an empty sequence
*/
public static Seq ofNullable(final T e, @SuppressWarnings("unused") final Class exceptionType) { //NOSONAR
if (e == null) {
return empty();
}
return of(e);
}
/**
* Creates a sequence from the provided array of elements.
*
* @param the type of elements in the stream
* @param the type of exception that might be thrown
* @param a the array of elements to be included in the sequence
* @return a sequence containing the provided elements
*/
@SafeVarargs
public static Seq of(final T... a) {
if (N.isEmpty(a)) {
return empty();
}
final int len = N.len(a);
return create(new Throwables.Iterator<>() {
private int position = 0;
@Override
public boolean hasNext() throws E {
return position < len;
}
@Override
public T next() throws E {
if (position >= len) {
throw new NoSuchElementException(ERROR_MSG_FOR_NO_SUCH_EX);
}
return a[position++];
}
@Override
public long count() throws E {
return len - position; //NOSONAR
}
@Override
public void advance(final long n) throws E {
if (n > len - position) {
position = len;
} else {
position += (int) n;
}
}
});
}
/**
* Creates a sequence from the provided boolean array.
*
* @param the type of exception that might be thrown
* @param a the boolean array to be included in the sequence
* @return a sequence containing the provided boolean elements
*/
public static Seq of(final boolean[] a) {
if (N.isEmpty(a)) {
return empty();
}
final int len = N.len(a);
return create(new Throwables.Iterator<>() {
private int position = 0;
@Override
public boolean hasNext() throws E {
return position < len;
}
@Override
public Boolean next() throws E {
return a[position++];
}
@Override
public long count() throws E {
return len - position; //NOSONAR
}
@Override
public void advance(final long n) throws E {
if (n > len - position) {
position = len;
} else {
position += (int) n;
}
}
});
}
/**
* Creates a sequence from the provided char array.
*
* @param the type of exception that might be thrown
* @param a the char array to be included in the sequence
* @return a sequence containing the provided char elements
*/
public static Seq of(final char[] a) {
if (N.isEmpty(a)) {
return empty();
}
final int len = N.len(a);
return create(new Throwables.Iterator<>() {
private int position = 0;
@Override
public boolean hasNext() throws E {
return position < len;
}
@Override
public Character next() throws E {
return a[position++];
}
@Override
public long count() throws E {
return len - position; //NOSONAR
}
@Override
public void advance(final long n) throws E {
if (n > len - position) {
position = len;
} else {
position += (int) n;
}
}
});
}
/**
* Creates a sequence from the provided byte array.
*
* @param the type of exception that might be thrown
* @param a the byte array to be included in the sequence
* @return a sequence containing the provided byte elements
*/
public static Seq of(final byte[] a) {
if (N.isEmpty(a)) {
return empty();
}
final int len = N.len(a);
return create(new Throwables.Iterator<>() {
private int position = 0;
@Override
public boolean hasNext() throws E {
return position < len;
}
@Override
public Byte next() throws E {
return a[position++];
}
@Override
public long count() throws E {
return len - position; //NOSONAR
}
@Override
public void advance(final long n) throws E {
if (n > len - position) {
position = len;
} else {
position += (int) n;
}
}
});
}
/**
* Creates a sequence from the provided short array.
*
* @param the type of exception that might be thrown
* @param a the short array to be included in the sequence
* @return a sequence containing the provided short elements
*/
public static Seq of(final short[] a) {
if (N.isEmpty(a)) {
return empty();
}
final int len = N.len(a);
return create(new Throwables.Iterator<>() {
private int position = 0;
@Override
public boolean hasNext() throws E {
return position < len;
}
@Override
public Short next() throws E {
return a[position++];
}
@Override
public long count() throws E {
return len - position; //NOSONAR
}
@Override
public void advance(final long n) throws E {
if (n > len - position) {
position = len;
} else {
position += (int) n;
}
}
});
}
/**
* Creates a sequence from the provided int array.
*
* @param the type of exception that might be thrown
* @param a the int array to be included in the sequence
* @return a sequence containing the provided int elements
*/
public static Seq of(final int[] a) {
if (N.isEmpty(a)) {
return empty();
}
final int len = N.len(a);
return create(new Throwables.Iterator<>() {
private int position = 0;
@Override
public boolean hasNext() throws E {
return position < len;
}
@Override
public Integer next() throws E {
return a[position++];
}
@Override
public long count() throws E {
return len - position; //NOSONAR
}
@Override
public void advance(final long n) throws E {
if (n > len - position) {
position = len;
} else {
position += (int) n;
}
}
});
}
/**
* Creates a sequence from the provided long array.
*
* @param the type of exception that might be thrown
* @param a the long array to be included in the sequence
* @return a sequence containing the provided long elements
*/
public static Seq of(final long[] a) {
if (N.isEmpty(a)) {
return empty();
}
final int len = N.len(a);
return create(new Throwables.Iterator<>() {
private int position = 0;
@Override
public boolean hasNext() throws E {
return position < len;
}
@Override
public Long next() throws E {
return a[position++];
}
@Override
public long count() throws E {
return len - position; //NOSONAR
}
@Override
public void advance(final long n) throws E {
if (n > len - position) {
position = len;
} else {
position += (int) n;
}
}
});
}
/**
* Creates a sequence from the provided float array.
*
* @param the type of exception that might be thrown
* @param a the float array to be included in the sequence
* @return a sequence containing the provided float elements
*/
public static Seq of(final float[] a) {
if (N.isEmpty(a)) {
return empty();
}
final int len = N.len(a);
return create(new Throwables.Iterator<>() {
private int position = 0;
@Override
public boolean hasNext() throws E {
return position < len;
}
@Override
public Float next() throws E {
return a[position++];
}
@Override
public long count() throws E {
return len - position; //NOSONAR
}
@Override
public void advance(final long n) throws E {
if (n > len - position) {
position = len;
} else {
position += (int) n;
}
}
});
}
/**
* Creates a sequence from the provided double array.
*
* @param the type of exception that might be thrown
* @param a the double array to be included in the sequence
* @return a sequence containing the provided double elements
*/
public static Seq of(final double[] a) {
if (N.isEmpty(a)) {
return empty();
}
final int len = N.len(a);
return create(new Throwables.Iterator<>() {
private int position = 0;
@Override
public boolean hasNext() throws E {
return position < len;
}
@Override
public Double next() throws E {
return a[position++];
}
@Override
public long count() throws E {
return len - position; //NOSONAR
}
@Override
public void advance(final long n) throws E {
if (n > len - position) {
position = len;
} else {
position += (int) n;
}
}
});
}
/**
* Returns a sequence containing the value of the specified Optional if it is present,
* otherwise returns an empty sequence.
*
* @param the type of the sequence elements
* @param the type of the exception that the sequence can throw
* @param op the Optional whose value is to be returned as a sequence
* @return a sequence containing the value of the specified Optional if it is present,
* otherwise an empty sequence
*/
public static Seq of(final Optional op) {
return op == null || op.isEmpty() ? Seq.empty() : Seq.of(op.get()); //NOSONAR
}
/**
* Returns a sequence containing the value of the specified Optional if it is present,
* otherwise returns an empty sequence.
*
* @param the type of the sequence elements
* @param the type of the exception that the sequence can throw
* @param op the Optional whose value is to be returned as a sequence
* @return a sequence containing the value of the specified Optional if it is present,
* otherwise an empty sequence
*/
public static Seq of(final java.util.Optional op) {
return op == null || op.isEmpty() ? Seq.empty() : Seq.of(op.get()); //NOSONAR
}
/**
* Creates a sequence from the provided Iterable of elements.
*
* @param the type of elements in the stream
* @param the type of exception that might be thrown
* @param iterable the Iterable of elements to be included in the sequence
* @return a sequence containing the provided elements
*/
public static Seq of(final Iterable extends T> iterable) {
if (iterable == null) {
return empty();
}
return of(iterable.iterator());
}
/**
* Creates a sequence from the provided Iterable of elements.
*
* @param the type of elements in the stream
* @param the type of exception that might be thrown
* @param iterable the Iterable of elements to be included in the sequence
* @param exceptionType the type of exception that might be thrown (not used)
* @return a sequence containing the provided elements
*/
public static Seq of(final Iterable extends T> iterable, @SuppressWarnings("unused") final Class exceptionType) { //NOSONAR
return of(iterable);
}
/**
* Creates a sequence from the provided Iterator of elements.
*
* @param the type of elements in the stream
* @param the type of exception that might be thrown
* @param iter the Iterator of elements to be included in the sequence
* @return a sequence containing the provided elements
*/
public static Seq of(final Iterator extends T> iter) {
if (iter == null) {
return empty();
}
return create(Throwables.Iterator. of(iter));
}
/**
* Creates a sequence from the provided Iterator of elements.
*
* @param the type of elements in the stream
* @param the type of exception that might be thrown
* @param iter the Iterator of elements to be included in the sequence
* @return a sequence containing the provided elements
*/
public static Seq of(final Throwables.Iterator extends T, ? extends E> iter) {
if (iter == null) {
return empty();
}
return create(iter);
}
/**
* Creates a sequence from the provided Iterator of elements.
*
* @param the type of elements in the stream
* @param the type of exception that might be thrown
* @param iter the Iterator of elements to be included in the sequence
* @param exceptionType the type of exception that might be thrown (not used)
* @return a sequence containing the provided elements
*/
public static Seq of(final Iterator extends T> iter, @SuppressWarnings("unused") final Class exceptionType) { //NOSONAR
return of(iter);
}
/**
* Creates a sequence from the provided Enumeration of elements.
*
* @param the type of elements in the stream
* @param the type of exception that might be thrown
* @param enumeration the Enumeration of elements to be included in the sequence
* @return a sequence containing the provided elements
*/
public static Seq of(final Enumeration extends T> enumeration) {
if (enumeration == null) {
return empty();
}
return of(Enumerations.toIterator(enumeration));
}
/**
* Creates a sequence from the provided Enumeration of elements.
*
* @param the type of elements in the stream
* @param the type of exception that might be thrown
* @param enumeration the Enumeration of elements to be included in the sequence
* @param exceptionType the type of exception that might be thrown (not used)
* @return a sequence containing the provided elements
*/
public static Seq of(final Enumeration extends T> enumeration, @SuppressWarnings("unused") final Class exceptionType) { //NOSONAR
return of(enumeration);
}
/**
* Creates a sequence from the provided Map of entries.
*
* @param the type of keys in the map
* @param the type of values in the map
* @param the type of exception that might be thrown
* @param m the Map of entries to be included in the sequence
* @return a sequence containing the provided map entries
*/
public static Seq, E> of(final Map m) {
if (N.isEmpty(m)) {
return empty();
}
return of(m.entrySet());
}
/**
* Creates a sequence from the provided Map of entries.
*
* @param the type of keys in the map
* @param the type of values in the map
* @param the type of exception that might be thrown
* @param m the Map of entries to be included in the sequence
* @param exceptionType the type of exception that might be thrown (not used)
* @return a sequence containing the provided map entries
*/
public static Seq, E> of(final Map m, @SuppressWarnings("unused") final Class exceptionType) { //NOSONAR
return of(m);
}
/**
* Creates a sequence from the keys of the provided Map.
*
* @param the type of keys in the map
* @param the type of exception that might be thrown
* @param map the Map whose keys are to be included in the sequence
* @return a sequence containing the keys of the provided Map
*/
public static Seq ofKeys(final Map map) {
if (N.isEmpty(map)) {
return empty();
}
return of(map.keySet());
}
/**
* Creates a sequence from the keys of the provided Map, filtered by the specified value predicate.
*
* @param the type of keys in the map
* @param the type of values in the map
* @param the type of exception that might be thrown
* @param map the Map whose keys are to be included in the sequence
* @param valueFilter the predicate to filter the values in the map
* @return a sequence containing the keys of the provided Map that match the value predicate
*/
public static Seq ofKeys(final Map map, final Throwables.Predicate super V, E> valueFilter) {
if (N.isEmpty(map)) {
return empty();
}
//noinspection resource
return Seq. of(map).filter(Fnn.testByValue(valueFilter)).map(Fnn.key());
}
/**
* Creates a sequence from the keys of the provided Map, filtered by the specified key-value predicate.
*
* @param the type of keys in the map
* @param the type of values in the map
* @param the type of exception that might be thrown
* @param map the Map whose keys are to be included in the sequence
* @param filter the predicate to filter the entries in the map
* @return a sequence containing the keys of the provided Map that match the key-value predicate
*/
public static Seq ofKeys(final Map map, final Throwables.BiPredicate super K, ? super V, E> filter) {
if (N.isEmpty(map)) {
return empty();
}
//noinspection resource
return Seq. of(map).filter(Fn.Entries.ep(filter)).map(Fnn.key());
}
/**
* Creates a sequence from the values of the provided Map.
*
* @param the type of values in the map
* @param the type of exception that might be thrown
* @param map the Map whose values are to be included in the sequence
* @return a sequence containing the values of the provided
*/
public static Seq ofValues(final Map, V> map) {
if (N.isEmpty(map)) {
return empty();
}
return of(map.values());
}
/**
* Creates a sequence from the values of the provided Map, filtered by the specified key predicate.
*
* @param the type of keys in the map
* @param the type of values in the map
* @param the type of exception that might be thrown
* @param map the Map whose values are to be included in the sequence
* @param keyFilter the predicate to filter the keys in the map
* @return a sequence containing the values of the provided Map that match the key predicate
*/
public static Seq ofValues(final Map map, final Throwables.Predicate super K, E> keyFilter) {
if (N.isEmpty(map)) {
return empty();
}
//noinspection resource
return Seq. of(map).filter(Fnn.testByKey(keyFilter)).map(Fnn.value());
}
/**
* Creates a sequence from the values of the provided Map, filtered by the specified key-value predicate.
*
* @param the type of keys in the map
* @param the type of values in the map
* @param the type of exception that might be thrown
* @param map the Map whose values are to be included in the sequence
* @param filter the predicate to filter the entries in the map
* @return a sequence containing the values of the provided Map that match the key-value predicate
*/
public static Seq ofValues(final Map map, final Throwables.BiPredicate super K, ? super V, E> filter) {
if (N.isEmpty(map)) {
return empty();
}
//noinspection resource
return Seq. of(map).filter(Fn.Entries.ep(filter)).map(Fnn.value());
}
/**
* Creates a sequence from the provided array in reverse order.
*
* @param the type of elements in the array
* @param the type of exception that might be thrown
* @param array the array of elements to be included in the sequence
* @return a sequence containing the elements of the provided array in reverse order
*/
public static Seq ofReversed(final T[] array) {
final int len = N.len(array);
//noinspection resource
return Seq. range(0, len).map(idx -> array[len - idx - 1]);
}
/**
* Creates a sequence from the provided list in reverse order.
*
* @param the type of elements in the list
* @param the type of exception that might be thrown
* @param list the list of elements to be included in the sequence
* @return a sequence containing the elements of the provided list in reverse order
*/
public static Seq ofReversed(final List extends T> list) {
final int size = N.size(list);
//noinspection resource
return Seq. range(0, size).map(idx -> list.get(size - idx - 1));
}
// /**
// * Creates a Seq that iterates using the provided hasNext and next functions.
// *
// * @param the type of elements in the stream
// * @param the type of exception that might be thrown
// * @param hasNext a BooleanSupplier that determines if there are more elements
// * @param next a Supplier that provides the next element
// * @return a Seq that iterates using the provided hasNext and next functions
// * @throws IllegalArgumentException if hasNext or next is null
// */
// public static Seq iterate(final Throwables.BooleanSupplier extends E> hasNext,
// final Throwables.Supplier extends T, E> next) throws IllegalArgumentException {
// N.checkArgNotNull(hasNext, cs.hasNext);
// N.checkArgNotNull(next, cs.next);
//
// return create(new Throwables.Iterator() {
// private boolean hasNextVal = false;
//
// @Override
// public boolean hasNext() throws E {
// if (!hasNextVal) {
// hasNextVal = hasNext.getAsBoolean();
// }
//
// return hasNextVal;
// }
//
// @Override
// public T next() throws E {
// if (!hasNextVal && !hasNext()) {
// throw new NoSuchElementException(ERROR_MSG_FOR_NO_SUCH_EX);
// }
//
// hasNextVal = false;
// return next.get();
// }
// });
// }
//
// /**
// * Creates a Seq that iterates starting from the given initial value,
// * using the provided hasNext function to determine if there are more elements
// * and the provided function to generate the next element.
// *
// * @param the type of elements in the stream
// * @param the type of exception that might be thrown
// * @param init the initial value
// * @param hasNext a BooleanSupplier that determines if there are more elements
// * @param f a UnaryOperator that provides the next element
// * @return a Seq that iterates using the provided hasNext and next functions
// * @throws IllegalArgumentException if hasNext or f is null
// */
// public static Seq iterate(final T init, final Throwables.BooleanSupplier extends E> hasNext,
// final Throwables.UnaryOperator f) throws IllegalArgumentException {
// N.checkArgNotNull(hasNext, cs.hasNext);
// N.checkArgNotNull(f, cs.f);
//
// return create(new Throwables.Iterator() {
// private T cur = (T) NONE;
// private boolean hasNextVal = false;
//
// @Override
// public boolean hasNext() throws E {
// if (!hasNextVal) {
// hasNextVal = hasNext.getAsBoolean();
// }
//
// return hasNextVal;
// }
//
// @Override
// public T next() throws E {
// if (!hasNextVal && !hasNext()) {
// throw new NoSuchElementException(ERROR_MSG_FOR_NO_SUCH_EX);
// }
//
// hasNextVal = false;
// return cur = (cur == NONE ? init : f.apply(cur));
// }
// });
// }
//
// /**
// * Creates a Seq that iterates starting from the given initial value,
// * using the provided hasNext function to determine if there are more elements
// * and the provided function to generate the next element.
// *
// * @param the type of elements in the stream
// * @param the type of exception that might be thrown
// * @param init the initial value
// * @param hasNext a Predicate that determines if there are more elements
// * @param f a UnaryOperator that provides the next element
// * @return a Seq that iterates using the provided hasNext and next functions
// * @throws IllegalArgumentException if hasNext or f is null
// */
// public static Seq iterate(final T init, final Throwables.Predicate super T, ? extends E> hasNext,
// final Throwables.UnaryOperator f) throws IllegalArgumentException {
// N.checkArgNotNull(hasNext, cs.hasNext);
// N.checkArgNotNull(f, cs.f);
//
// return create(new Throwables.Iterator() {
// private T cur = (T) NONE;
// private boolean hasMore = true;
// private boolean hasNextVal = false;
//
// @Override
// public boolean hasNext() throws E {
// if (!hasNextVal && hasMore) {
// hasNextVal = hasNext.test((cur = (cur == NONE ? init : f.apply(cur))));
//
// if (!hasNextVal) {
// hasMore = false;
// }
// }
//
// return hasNextVal;
// }
//
// @Override
// public T next() throws E {
// if (!hasNextVal && !hasNext()) {
// throw new NoSuchElementException(ERROR_MSG_FOR_NO_SUCH_EX);
// }
//
// hasNextVal = false;
// return cur;
// }
// });
// }
//
// /**
// * Creates a Seq that iterates starting from the given initial value,
// * using the provided function to generate the next element.
// *
// * @param the type of elements in the stream
// * @param the type of exception that might be thrown
// * @param init the initial value
// * @param f a UnaryOperator that provides the next element
// * @return a Seq that iterates using the provided function
// * @throws IllegalArgumentException if f is null
// */
// public static Seq iterate(final T init, final Throwables.UnaryOperator f) throws IllegalArgumentException {
// N.checkArgNotNull(f, cs.f);
//
// return create(new Throwables.Iterator() {
// private T cur = (T) NONE;
//
// @Override
// public boolean hasNext() throws E {
// return true;
// }
//
// @Override
// public T next() throws E { // NOSONAR
// return cur = (cur == NONE ? init : f.apply(cur));
// }
// });
// }
//
// /**
// * Generates a Seq using the provided supplier.
// *
// * @param the type of the stream elements
// * @param the type of the exception that the stream can throw
// * @param supplier the supplier to generate elements for the stream
// * @return a Seq generated by the supplier
// * @throws IllegalArgumentException if the supplier is null
// */
// public static Seq generate(final Throwables.Supplier supplier) throws IllegalArgumentException {
// N.checkArgNotNull(supplier, cs.supplier);
//
// return create(new Throwables.Iterator