com.landawn.abacus.util.ExceptionalStream 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) 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.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Reader;
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.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.Spliterator;
import java.util.Spliterators;
import java.util.concurrent.Executor;
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.stream.Collector;
import java.util.stream.StreamSupport;
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.TerminalOp;
import com.landawn.abacus.annotation.TerminalOpTriggered;
import com.landawn.abacus.exception.TooManyElementsException;
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.Strings.StringUtil;
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.stream.Collectors;
import com.landawn.abacus.util.stream.DoubleStream;
import com.landawn.abacus.util.stream.IntStream;
import com.landawn.abacus.util.stream.LongStream;
import com.landawn.abacus.util.stream.ObjIteratorEx;
import com.landawn.abacus.util.stream.Stream;
/**
* The Stream will be automatically closed after execution(A terminal method is executed/triggered).
*
* @author Haiyang Li
* @param
* @param
* @since 1.3
*
* @see BaseStream
* @see Stream
* @see IntStream
* @see LongStream
* @see DoubleStream
* @see Collectors
* @see com.landawn.abacus.util.Fn.Fnn
* @see com.landawn.abacus.util.Comparators
* @see com.landawn.abacus.util.ExceptionUtil
*/
@LazyEvaluation
@SequentialOnly
@com.landawn.abacus.annotation.Immutable
@SuppressWarnings("java:S1192")
public class ExceptionalStream implements Closeable, Immutable {
static final Logger logger = LoggerFactory.getLogger(ExceptionalStream.class);
static final Object NONE = N.NULL_MASK;
static final Random RAND = new SecureRandom();
static final Throwables.Function GET_AS_INT = OptionalInt::get;
static final Throwables.Function GET_AS_LONG = OptionalLong::get;
static final Throwables.Function GET_AS_DOUBLE = OptionalDouble::get;
@SuppressWarnings("rawtypes")
static final Throwables.Function GET_AS_IT = it -> it.orElse(null);
static final Throwables.Function GET_AS_INT_JDK = java.util.OptionalInt::getAsInt;
static final Throwables.Function GET_AS_LONG_JDK = java.util.OptionalLong::getAsLong;
static final Throwables.Function GET_AS_DOUBLE_JDK = java.util.OptionalDouble::getAsDouble;
@SuppressWarnings("rawtypes")
static final Throwables.Function GET_AS_IT_JDK = it -> it.orElse(null);
static final Throwables.Predicate IS_PRESENT_INT = OptionalInt::isPresent;
static final Throwables.Predicate IS_PRESENT_LONG = OptionalLong::isPresent;
static final Throwables.Predicate IS_PRESENT_DOUBLE = OptionalDouble::isPresent;
@SuppressWarnings("rawtypes")
static final Throwables.Predicate IS_PRESENT_IT = Optional::isPresent;
static final Throwables.Predicate IS_PRESENT_INT_JDK = java.util.OptionalInt::isPresent;
static final Throwables.Predicate IS_PRESENT_LONG_JDK = java.util.OptionalLong::isPresent;
static final Throwables.Predicate IS_PRESENT_DOUBLE_JDK = java.util.OptionalDouble::isPresent;
@SuppressWarnings("rawtypes")
static final Throwables.Predicate IS_PRESENT_IT_JDK = java.util.Optional::isPresent;
static final Throwables.Function, Object>, Object, Exception> KK = t -> t.getKey().val();
private final ExceptionalIterator elements;
private final boolean sorted;
private final Comparator cmp;
private final Deque> closeHandlers;
private boolean isClosed = false;
ExceptionalStream(final ExceptionalIterator iter) {
this(iter, false, null, null);
}
ExceptionalStream(final ExceptionalIterator iter, final Deque> closeHandlers) {
this(iter, false, null, closeHandlers);
}
ExceptionalStream(final ExceptionalIterator iter, final boolean sorted, final Comparator comparator,
final Deque> closeHandlers) {
this.elements = iter;
this.sorted = sorted;
this.cmp = comparator;
this.closeHandlers = closeHandlers;
}
/**
*
* @param
* @param
* @return
*/
public static ExceptionalStream empty() {
return new ExceptionalStream<>(ExceptionalIterator.EMPTY);
}
/**
*
* @param
* @param
* @param e
* @return
*/
public static ExceptionalStream just(final T e) {
return of(e);
}
/**
*
* @param
* @param
* @param e
* @param exceptionType
* @return
*/
public static ExceptionalStream just(final T e, @SuppressWarnings("unused") final Class exceptionType) { //NOSONAR
return of(e);
}
/**
* Returns an empty {@code Stream} if the specified {@code t} is null.
*
* @param
* @param
* @param e
* @return
*/
public static ExceptionalStream ofNullable(final T e) {
if (e == null) {
return empty();
}
return of(e);
}
/**
* Returns an empty {@code Stream} if the specified {@code t} is null.
*
* @param
* @param
* @param e
* @param exceptionType
* @return
*/
public static ExceptionalStream ofNullable(final T e, @SuppressWarnings("unused") final Class exceptionType) { //NOSONAR
if (e == null) {
return empty();
}
return of(e);
}
/**
*
* @param
* @param
* @param a
* @return
* @see Stream.of(T[]).checked(SomeCheckedException.class)...
*/
public static ExceptionalStream of(final T... a) {
if (N.isNullOrEmpty(a)) {
return empty();
}
final int len = N.len(a);
return newStream(new ExceptionalIterator() {
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();
}
return a[position++];
}
@Override
public long count() throws E {
return len - position; //NOSONAR
}
@Override
public void advance(long n) throws E {
if (n > len - position) {
position = len;
} else {
position += n;
}
}
});
}
/**
*
* @param
* @param
* @param c
* @return
*/
public static ExceptionalStream of(final Collection c) {
if (N.isNullOrEmpty(c)) {
return empty();
}
@SuppressWarnings("deprecation")
final T[] a = (T[]) InternalUtil.getInternalArray(c);
if (a != null) {
final int len = c.size();
return newStream(new ExceptionalIterator() {
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();
}
return a[position++];
}
@Override
public long count() throws E {
return len - position; //NOSONAR
}
@Override
public void advance(long n) throws E {
if (n > len - position) {
position = len;
} else {
position += n;
}
}
});
}
return of(c.iterator());
}
/**
*
* @param
* @param
* @param iter
* @return
*/
public static ExceptionalStream of(final Iterator iter) {
if (iter == null) {
return empty();
}
return newStream(ExceptionalIterator. of(iter));
}
/**
*
* @param
* @param
* @param iterable
* @return
*/
public static ExceptionalStream of(final Iterable iterable) {
if (iterable == null) {
return empty();
}
if (iterable instanceof Collection) {
return of((Collection) iterable);
} else {
return of(iterable.iterator());
}
}
/**
*
* @param the key type
* @param the value type
* @param
* @param m
* @return
*/
public static ExceptionalStream, E> of(final Map m) {
if (N.isNullOrEmpty(m)) {
return empty();
}
return of(m.entrySet());
}
/**
*
* @param
* @param
* @param stream
* @return
*/
public static ExceptionalStream of(final Stream stream) {
return checked(stream, false);
}
/**
*
* @param
* @param
* @param stream
* @return
*/
public static ExceptionalStream of(final java.util.stream.Stream stream) {
if (stream == null) {
return empty();
}
return ExceptionalStream. of(stream.iterator()).onClose(stream::close);
}
/**
*
* @param
* @param
* @param c
* @param exceptionType
* @return
*/
public static ExceptionalStream of(final Collection c,
@SuppressWarnings("unused") final Class exceptionType) { //NOSONAR
return of(c);
}
/**
*
* @param
* @param
* @param iter
* @param exceptionType
* @return
*/
public static ExceptionalStream of(final Iterator iter,
@SuppressWarnings("unused") final Class exceptionType) { //NOSONAR
return of(iter);
}
/**
*
* @param
* @param
* @param iterable
* @param exceptionType
* @return
*/
public static ExceptionalStream of(final Iterable iterable,
@SuppressWarnings("unused") final Class exceptionType) { //NOSONAR
return of(iterable);
}
/**
*
* @param the key type
* @param the value type
* @param
* @param m
* @param exceptionType
* @return
*/
public static ExceptionalStream, E> of(final Map m,
@SuppressWarnings("unused") final Class exceptionType) { //NOSONAR
return of(m);
}
/**
*
* @param
* @param
* @param stream
* @param exceptionType
* @return
*/
public static ExceptionalStream of(final Stream stream,
@SuppressWarnings("unused") final Class exceptionType) { //NOSONAR
return of(stream);
}
/**
*
* @param
* @param
* @param stream
* @param exceptionType
* @return
*/
public static ExceptionalStream of(final java.util.stream.Stream stream,
@SuppressWarnings("unused") final Class exceptionType) { //NOSONAR
return of(stream);
}
/**
*
*
* @param
* @param a
* @return
*/
public static ExceptionalStream of(final boolean[] a) {
if (N.isNullOrEmpty(a)) {
return empty();
}
final int len = N.len(a);
return newStream(new ExceptionalIterator() {
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(long n) throws E {
if (n > len - position) {
position = len;
} else {
position += n;
}
}
});
}
/**
*
*
* @param
* @param a
* @return
*/
public static ExceptionalStream of(final char[] a) {
if (N.isNullOrEmpty(a)) {
return empty();
}
final int len = N.len(a);
return newStream(new ExceptionalIterator() {
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(long n) throws E {
if (n > len - position) {
position = len;
} else {
position += n;
}
}
});
}
/**
*
*
* @param
* @param a
* @return
*/
public static ExceptionalStream of(final byte[] a) {
if (N.isNullOrEmpty(a)) {
return empty();
}
final int len = N.len(a);
return newStream(new ExceptionalIterator() {
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(long n) throws E {
if (n > len - position) {
position = len;
} else {
position += n;
}
}
});
}
/**
*
*
* @param
* @param a
* @return
*/
public static ExceptionalStream of(final short[] a) {
if (N.isNullOrEmpty(a)) {
return empty();
}
final int len = N.len(a);
return newStream(new ExceptionalIterator() {
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(long n) throws E {
if (n > len - position) {
position = len;
} else {
position += n;
}
}
});
}
/**
*
* @param
* @param a
* @return
*/
public static ExceptionalStream of(final int[] a) {
if (N.isNullOrEmpty(a)) {
return empty();
}
final int len = N.len(a);
return newStream(new ExceptionalIterator() {
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(long n) throws E {
if (n > len - position) {
position = len;
} else {
position += n;
}
}
});
}
/**
*
* @param
* @param a
* @return
*/
public static ExceptionalStream of(final long[] a) {
if (N.isNullOrEmpty(a)) {
return empty();
}
final int len = N.len(a);
return newStream(new ExceptionalIterator() {
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(long n) throws E {
if (n > len - position) {
position = len;
} else {
position += n;
}
}
});
}
/**
*
*
* @param
* @param a
* @return
*/
public static ExceptionalStream of(final float[] a) {
if (N.isNullOrEmpty(a)) {
return empty();
}
final int len = N.len(a);
return newStream(new ExceptionalIterator() {
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(long n) throws E {
if (n > len - position) {
position = len;
} else {
position += n;
}
}
});
}
/**
*
* @param
* @param a
* @return
*/
public static ExceptionalStream of(final double[] a) {
if (N.isNullOrEmpty(a)) {
return empty();
}
final int len = N.len(a);
return newStream(new ExceptionalIterator() {
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(long n) throws E {
if (n > len - position) {
position = len;
} else {
position += n;
}
}
});
}
/**
*
*
* @param
* @param
* @param op
* @return
*/
public static ExceptionalStream of(final Optional op) {
return op == null || !op.isPresent() ? ExceptionalStream. empty() : ExceptionalStream. of(op.get()); //NOSONAR
}
/**
*
*
* @param
* @param
* @param op
* @return
*/
public static ExceptionalStream of(final java.util.Optional op) {
return op == null || !op.isPresent() ? ExceptionalStream. empty() : ExceptionalStream. of(op.get()); //NOSONAR
}
/**
*
*
* @param
* @param
* @param map
* @return
*/
public static ExceptionalStream ofKeys(final Map map) {
if (N.isNullOrEmpty(map)) {
return empty();
}
return of(map.keySet());
}
/**
*
*
* @param
* @param
* @param
* @param map
* @param valueFilter
* @return
*/
public static ExceptionalStream ofKeys(final Map map, final Throwables.Predicate valueFilter) {
if (N.isNullOrEmpty(map)) {
return empty();
}
return ExceptionalStream. of(map).filter(Fnn. testByValue(valueFilter)).map(Fnn. key());
}
/**
*
*
* @param
* @param
* @param
* @param map
* @param filter
* @return
*/
public static ExceptionalStream ofKeys(final Map map,
final Throwables.BiPredicate filter) {
if (N.isNullOrEmpty(map)) {
return empty();
}
return ExceptionalStream. of(map).filter(Fn.Entries.ep(filter)).map(Fnn. key());
}
/**
*
*
* @param
* @param
* @param map
* @return
*/
public static ExceptionalStream ofValues(final Map map) {
if (N.isNullOrEmpty(map)) {
return empty();
}
return of(map.values());
}
/**
*
*
* @param
* @param
* @param
* @param map
* @param keyFilter
* @return
*/
public static ExceptionalStream ofValues(final Map map, final Throwables.Predicate keyFilter) {
if (N.isNullOrEmpty(map)) {
return empty();
}
return ExceptionalStream. of(map).filter(Fnn. testByKey(keyFilter)).map(Fnn. value());
}
/**
*
*
* @param
* @param
* @param
* @param map
* @param filter
* @return
*/
public static ExceptionalStream ofValues(final Map map,
final Throwables.BiPredicate filter) {
if (N.isNullOrEmpty(map)) {
return empty();
}
return ExceptionalStream. of(map).filter(Fn.Entries.ep(filter)).map(Fnn. value());
}
// /**
// * Lazy evaluation.
// *
// *
// * This is equal to: {@code ExceptionalStream.just(supplier).flatmap(it -> it.get())}.
// *
// * @param supplier
// * @return
// */
// @Beta
// public static ExceptionalStream from(final Throwables.Supplier, ? extends E> supplier) {
// N.checkArgNotNull(supplier, "supplier");
//
// return ExceptionalStream., ? extends E>, E> just(supplier)
// .flatmap(Throwables.Supplier::get);
// }
/**
* Lazy evaluation.
*
*
* This is equal to: {@code ExceptionalStream.just(supplier).flatMap(it -> it.get())}.
*
* @param
* @param
* @param supplier
* @return
*/
public static ExceptionalStream defer(
final Throwables.Supplier, ? extends E> supplier) {
N.checkArgNotNull(supplier, "supplier");
return ExceptionalStream., ? extends E>, E> just(supplier)
.flatMap(Throwables.Supplier::get);
}
/**
*
* @param
* @param
* @param hasNext
* @param next
* @return
*/
public static ExceptionalStream iterate(final Throwables.BooleanSupplier hasNext,
final Throwables.Supplier next) {
N.checkArgNotNull(hasNext, "hasNext");
N.checkArgNotNull(next, "next");
return newStream(new ExceptionalIterator() {
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();
}
hasNextVal = false;
return next.get();
}
});
}
/**
*
* @param
* @param
* @param init
* @param hasNext
* @param f
* @return
*/
public static ExceptionalStream iterate(final T init, final Throwables.BooleanSupplier hasNext,
final Throwables.UnaryOperator f) {
N.checkArgNotNull(hasNext, "hasNext");
N.checkArgNotNull(f, "f");
return newStream(new ExceptionalIterator() {
private final T none = (T) NONE;
private T 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();
}
hasNextVal = false;
return t = (t == none) ? init : f.apply(t);
}
});
}
/**
*
* @param
* @param
* @param init
* @param hasNext
* @param f
* @return
*/
public static ExceptionalStream iterate(final T init, final Throwables.Predicate hasNext,
final Throwables.UnaryOperator f) {
N.checkArgNotNull(hasNext, "hasNext");
N.checkArgNotNull(f, "f");
return newStream(new ExceptionalIterator() {
private final T none = (T) NONE;
private T t = none;
private T cur = none;
private boolean hasMore = true;
private boolean hasNextVal = false;
@Override
public boolean hasNext() throws E {
if (!hasNextVal && hasMore) {
hasNextVal = hasNext.test((cur = (t == none ? init : f.apply(t))));
if (!hasNextVal) {
hasMore = false;
}
}
return hasNextVal;
}
@Override
public T next() throws E {
if (!hasNextVal && !hasNext()) {
throw new NoSuchElementException();
}
t = cur;
cur = none;
hasNextVal = false;
return t;
}
});
}
/**
*
* @param
* @param
* @param init
* @param f
* @return
*/
public static ExceptionalStream iterate(final T init, final Throwables.UnaryOperator f) {
N.checkArgNotNull(f, "f");
return newStream(new ExceptionalIterator() {
private final T none = (T) NONE;
private T t = none;
@Override
public boolean hasNext() throws E {
return true;
}
@Override
public T next() throws E {
return t = t == none ? init : f.apply(t);
}
});
}
/**
*
*
* @param
* @param
* @param supplier
* @return
*/
public static ExceptionalStream generate(final Throwables.Supplier supplier) {
N.checkArgNotNull(supplier, "supplier");
return newStream(new ExceptionalIterator() {
@Override
public boolean hasNext() throws E {
return true;
}
@Override
public T next() throws E {
return supplier.get();
}
});
}
/**
*
*
* @param
* @param
* @param element
* @param n
* @return
*/
public static ExceptionalStream repeat(final T element, final long n) {
N.checkArgNotNegative(n, "n");
if (n == 0) {
return empty();
}
return newStream(new ExceptionalIterator() {
private long cnt = n;
@Override
public boolean hasNext() throws E {
return cnt > 0;
}
@Override
public T next() throws E {
if (cnt-- <= 0) {
throw new NoSuchElementException();
}
return element;
}
});
}
/**
*
*
* @param
* @param startInclusive
* @param endExclusive
* @return
*/
public static ExceptionalStream range(final int startInclusive, final int endExclusive) {
return IntStream.range(startInclusive, endExclusive).boxed(). checked();
}
/**
*
*
* @param