com.landawn.abacus.util.stream.StreamBase 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) 2016, 2017, 2018, 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.stream;
import java.lang.reflect.Field;
import java.security.SecureRandom;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Deque;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import com.landawn.abacus.logging.Logger;
import com.landawn.abacus.logging.LoggerFactory;
import com.landawn.abacus.util.AsyncExecutor;
import com.landawn.abacus.util.BiMap;
import com.landawn.abacus.util.BooleanList;
import com.landawn.abacus.util.ByteIterator;
import com.landawn.abacus.util.ByteList;
import com.landawn.abacus.util.CharIterator;
import com.landawn.abacus.util.CharList;
import com.landawn.abacus.util.Comparators;
import com.landawn.abacus.util.ContinuableFuture;
import com.landawn.abacus.util.DoubleIterator;
import com.landawn.abacus.util.DoubleList;
import com.landawn.abacus.util.FloatIterator;
import com.landawn.abacus.util.FloatList;
import com.landawn.abacus.util.Fn;
import com.landawn.abacus.util.IOUtil;
import com.landawn.abacus.util.ImmutableList;
import com.landawn.abacus.util.ImmutableSet;
import com.landawn.abacus.util.Indexed;
import com.landawn.abacus.util.IndexedByte;
import com.landawn.abacus.util.IndexedChar;
import com.landawn.abacus.util.IndexedDouble;
import com.landawn.abacus.util.IndexedFloat;
import com.landawn.abacus.util.IndexedInt;
import com.landawn.abacus.util.IndexedLong;
import com.landawn.abacus.util.IndexedShort;
import com.landawn.abacus.util.IntIterator;
import com.landawn.abacus.util.IntList;
import com.landawn.abacus.util.LongIterator;
import com.landawn.abacus.util.LongList;
import com.landawn.abacus.util.LongMultiset;
import com.landawn.abacus.util.Multimap;
import com.landawn.abacus.util.Multiset;
import com.landawn.abacus.util.MutableBoolean;
import com.landawn.abacus.util.N;
import com.landawn.abacus.util.Sheet;
import com.landawn.abacus.util.ShortIterator;
import com.landawn.abacus.util.ShortList;
import com.landawn.abacus.util.Try;
import com.landawn.abacus.util.Wrapper;
import com.landawn.abacus.util.u.Holder;
import com.landawn.abacus.util.function.BiConsumer;
import com.landawn.abacus.util.function.BinaryOperator;
/**
*
*/
abstract class StreamBase>
implements BaseStream {
static final Logger logger = LoggerFactory.getLogger(StreamBase.class);
static final Object NONE = new Object();
static final Runnable EMPTY_CLOSE_HANDLER = new Runnable() {
@Override
public void run() {
// do nothing.
}
};
static final int MAX_THREAD_POOL_SIZE = 8192;
// static final int MAX_THREAD_POOL_SIZE = Integer.MAX_VALUE;
static final int MAX_THREAD_NUM_PER_OPERATION = 1024;
static final int CORE_THREAD_POOL_SIZE = 64;
static final int DEFAULT_MAX_THREAD_NUM = Math.max(8, IOUtil.CPU_CORES * 2);
static final int DEFAULT_READING_THREAD_NUM = Math.max(8, IOUtil.CPU_CORES * 2);
static final int MAX_QUEUE_SIZE = 8192;
static final int DEFAULT_QUEUE_SIZE_PER_ITERATOR = 64;
static final Splitor DEFAULT_SPLITOR = Splitor.ITERATOR;
static final Random RAND = new SecureRandom();
static final AsyncExecutor DEFAULT_ASYNC_EXECUTOR;
static {
final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(CORE_THREAD_POOL_SIZE, MAX_THREAD_POOL_SIZE, 0L, TimeUnit.SECONDS,
new LinkedBlockingQueue(1));
DEFAULT_ASYNC_EXECUTOR = new AsyncExecutor(threadPoolExecutor) {
@Override
public ContinuableFuture execute(final Try.Runnable extends Exception> command) {
// if (threadPoolExecutor.getActiveCount() >= MAX_THREAD_POOL_SIZE) {
// throw new RejectedExecutionException("Task is rejected due to exceed max thread pool size: " + MAX_THREAD_POOL_SIZE);
// }
return super.execute(command);
}
@Override
public ContinuableFuture execute(final Callable command) {
// if (threadPoolExecutor.getActiveCount() >= MAX_THREAD_POOL_SIZE) {
// throw new RejectedExecutionException("Task is rejected due to exceed max thread pool size: " + MAX_THREAD_POOL_SIZE);
// }
return super.execute(command);
}
};
}
@SuppressWarnings("rawtypes")
static final Comparator NATURAL_COMPARATOR = Comparators.naturalOrder();
@SuppressWarnings("rawtypes")
static final Comparator REVERSED_COMPARATOR = Comparators.reversedOrder();
static final Comparator CHAR_COMPARATOR = new Comparator() {
@Override
public int compare(Character o1, Character o2) {
return Character.compare(o1, o2);
}
};
static final Comparator BYTE_COMPARATOR = new Comparator() {
@Override
public int compare(Byte o1, Byte o2) {
return Byte.compare(o1, o2);
}
};
static final Comparator SHORT_COMPARATOR = new Comparator() {
@Override
public int compare(Short o1, Short o2) {
return Short.compare(o1, o2);
}
};
static final Comparator INT_COMPARATOR = new Comparator() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2);
}
};
static final Comparator LONG_COMPARATOR = new Comparator() {
@Override
public int compare(Long o1, Long o2) {
return Long.compare(o1, o2);
}
};
static final Comparator FLOAT_COMPARATOR = new Comparator() {
@Override
public int compare(Float o1, Float o2) {
return Float.compare(o1, o2);
}
};
static final Comparator DOUBLE_COMPARATOR = new Comparator() {
@Override
public int compare(Double o1, Double o2) {
return Double.compare(o1, o2);
}
};
static final Comparator INDEXED_BYTE_COMPARATOR = new Comparator() {
@Override
public int compare(IndexedByte a, IndexedByte b) {
return N.compare(a.longIndex(), b.longIndex());
}
};
static final Comparator INDEXED_CHAR_COMPARATOR = new Comparator() {
@Override
public int compare(IndexedChar a, IndexedChar b) {
return N.compare(a.longIndex(), b.longIndex());
}
};
static final Comparator INDEXED_SHORT_COMPARATOR = new Comparator() {
@Override
public int compare(IndexedShort a, IndexedShort b) {
return N.compare(a.longIndex(), b.longIndex());
}
};
static final Comparator INDEXED_INT_COMPARATOR = new Comparator() {
@Override
public int compare(IndexedInt a, IndexedInt b) {
return N.compare(a.longIndex(), b.longIndex());
}
};
static final Comparator INDEXED_LONG_COMPARATOR = new Comparator() {
@Override
public int compare(IndexedLong a, IndexedLong b) {
return N.compare(a.longIndex(), b.longIndex());
}
};
static final Comparator INDEXED_FLOAT_COMPARATOR = new Comparator() {
@Override
public int compare(IndexedFloat a, IndexedFloat b) {
return N.compare(a.longIndex(), b.longIndex());
}
};
static final Comparator INDEXED_DOUBLE_COMPARATOR = new Comparator() {
@Override
public int compare(IndexedDouble a, IndexedDouble b) {
return N.compare(a.longIndex(), b.longIndex());
}
};
static final Comparator> INDEXED_COMPARATOR = new Comparator>() {
@Override
public int compare(Indexed> a, Indexed> b) {
return N.compare(a.longIndex(), b.longIndex());
}
};
static final BiMap, Comparator>> defaultComparator = new BiMap<>();
static {
defaultComparator.put(char.class, CHAR_COMPARATOR);
defaultComparator.put(byte.class, BYTE_COMPARATOR);
defaultComparator.put(short.class, SHORT_COMPARATOR);
defaultComparator.put(int.class, INT_COMPARATOR);
defaultComparator.put(long.class, LONG_COMPARATOR);
defaultComparator.put(float.class, FLOAT_COMPARATOR);
defaultComparator.put(double.class, DOUBLE_COMPARATOR);
defaultComparator.put(Object.class, NATURAL_COMPARATOR);
}
static final Map, Integer> clsNum = new BiMap<>();
static {
int idx = 0;
clsNum.put(boolean[].class, idx++); // 0
clsNum.put(char[].class, idx++);
clsNum.put(byte[].class, idx++);
clsNum.put(short[].class, idx++);
clsNum.put(int[].class, idx++);
clsNum.put(long[].class, idx++);
clsNum.put(float[].class, idx++);
clsNum.put(double[].class, idx++); // 7
clsNum.put(BooleanList.class, idx++); // 8
clsNum.put(CharList.class, idx++);
clsNum.put(ByteList.class, idx++);
clsNum.put(ShortList.class, idx++);
clsNum.put(IntList.class, idx++);
clsNum.put(LongList.class, idx++);
clsNum.put(FloatList.class, idx++);
clsNum.put(DoubleList.class, idx++); // 15
}
@SuppressWarnings("rawtypes")
static final BinaryOperator reducingCombiner = new BinaryOperator() {
@Override
public Object apply(Object t, Object u) {
if (t instanceof Multiset) {
final Multiset a = (Multiset) t;
final Multiset b = (Multiset) u;
if (a.size() >= b.size()) {
a.addAll(b);
return a;
} else {
b.addAll(a);
return b;
}
} else if (t instanceof LongMultiset) {
final LongMultiset a = (LongMultiset) t;
final LongMultiset b = (LongMultiset) u;
if (a.size() >= b.size()) {
a.addAll(b);
return a;
} else {
b.addAll(a);
return b;
}
} else if (t instanceof Multimap) {
final Multimap a = (Multimap) t;
final Multimap b = (Multimap) u;
if (a.size() >= b.size()) {
a.putAll(b);
return a;
} else {
b.putAll(a);
return b;
}
} else if (t instanceof Collection) {
final Collection a = (Collection) t;
final Collection b = (Collection) u;
if (a.size() >= b.size()) {
a.addAll(b);
return a;
} else {
b.addAll(a);
return b;
}
} else if (t instanceof Map) {
final Map a = (Map) t;
final Map b = (Map) u;
if (a.size() >= b.size()) {
a.putAll(b);
return a;
} else {
b.putAll(a);
return b;
}
} else if (t instanceof Object[]) {
return N.concat((Object[]) t, (Object[]) u);
} else if (t instanceof StringBuilder) {
final StringBuilder a = (StringBuilder) t;
final StringBuilder b = (StringBuilder) u;
if (a.length() >= b.length()) {
a.append(b);
return a;
} else {
b.append(a);
return b;
}
} else if (t instanceof String) {
return (String) t + (String) u;
} else if (t instanceof Sheet) {
final Sheet a = (Sheet) t;
final Sheet b = (Sheet) u;
if (a.rowLength() >= b.rowLength()) {
a.putAll(b);
return a;
} else {
b.putAll(a);
return b;
}
} else {
final Class> cls = t.getClass();
final Integer num = clsNum.get(cls);
if (num == null) {
throw new RuntimeException(cls.getCanonicalName()
+ " can't be combined by default. Only Map/Collection/StringBuilder/String/Multiset/LongMultiset/Multimap/Sheet/BooleanList ... List/boolean[] ... Object[] are supported");
}
switch (num.intValue()) {
case 0:
return N.concat((boolean[]) t, (boolean[]) u);
case 1:
return N.concat((char[]) t, (char[]) u);
case 2:
return N.concat((byte[]) t, (byte[]) u);
case 3:
return N.concat((short[]) t, (short[]) u);
case 4:
return N.concat((int[]) t, (int[]) u);
case 5:
return N.concat((long[]) t, (long[]) u);
case 6:
return N.concat((float[]) t, (float[]) u);
case 7:
return N.concat((double[]) t, (double[]) u);
case 8: {
final BooleanList a = (BooleanList) t;
final BooleanList b = (BooleanList) u;
if (a.size() >= b.size()) {
a.addAll(b);
return a;
} else {
b.addAll(a);
return b;
}
}
case 9: {
final CharList a = (CharList) t;
final CharList b = (CharList) u;
if (a.size() >= b.size()) {
a.addAll(b);
return a;
} else {
b.addAll(a);
return b;
}
}
case 10: {
final ByteList a = (ByteList) t;
final ByteList b = (ByteList) u;
if (a.size() >= b.size()) {
a.addAll(b);
return a;
} else {
b.addAll(a);
return b;
}
}
case 11: {
final ShortList a = (ShortList) t;
final ShortList b = (ShortList) u;
if (a.size() >= b.size()) {
a.addAll(b);
return a;
} else {
b.addAll(a);
return b;
}
}
case 12: {
final IntList a = (IntList) t;
final IntList b = (IntList) u;
if (a.size() >= b.size()) {
a.addAll(b);
return a;
} else {
b.addAll(a);
return b;
}
}
case 13: {
final LongList a = (LongList) t;
final LongList b = (LongList) u;
if (a.size() >= b.size()) {
a.addAll(b);
return a;
} else {
b.addAll(a);
return b;
}
}
case 14: {
final FloatList a = (FloatList) t;
final FloatList b = (FloatList) u;
if (a.size() >= b.size()) {
a.addAll(b);
return a;
} else {
b.addAll(a);
return b;
}
}
case 15: {
final DoubleList a = (DoubleList) t;
final DoubleList b = (DoubleList) u;
if (a.size() >= b.size()) {
a.addAll(b);
return a;
} else {
b.addAll(a);
return b;
}
}
default:
throw new RuntimeException(cls.getCanonicalName()
+ " can't be combined by default. Only Map/Collection/StringBuilder/String/Multiset/LongMultiset/Multimap/Sheet/BooleanList ... List/boolean[] ... Object[] are supported");
}
}
}
};
@SuppressWarnings("rawtypes")
static final BiConsumer collectingCombiner = new BiConsumer() {
@Override
public void accept(Object t, Object u) {
if (t instanceof Multiset) {
((Multiset) t).addAll((Multiset) u);
} else if (t instanceof LongMultiset) {
((LongMultiset) t).addAll((LongMultiset) u);
} else if (t instanceof Multimap) {
((Multimap) t).putAll((Multimap) u);
} else if (t instanceof Collection) {
((Collection) t).addAll((Collection) u);
} else if (t instanceof Map) {
((Map) t).putAll((Map) u);
} else if (t instanceof StringBuilder) {
((StringBuilder) t).append((StringBuilder) u);
} else if (t instanceof Sheet) {
((Sheet) t).putAll((Sheet) u);
} else {
final Class> cls = t.getClass();
Integer num = clsNum.get(cls);
if (num == null) {
throw new RuntimeException(cls.getCanonicalName()
+ " can't be combined by default. Only Map/Collection/StringBuilder/Multiset/LongMultiset/Multimap/Sheet/BooleanList ... List are supported");
}
switch (num.intValue()) {
case 8:
((BooleanList) t).addAll((BooleanList) u);
break;
case 9:
((CharList) t).addAll((CharList) u);
break;
case 10:
((ByteList) t).addAll((ByteList) u);
break;
case 11:
((ShortList) t).addAll((ShortList) u);
break;
case 12:
((IntList) t).addAll((IntList) u);
break;
case 13:
((LongList) t).addAll((LongList) u);
break;
case 14:
((FloatList) t).addAll((FloatList) u);
break;
case 15:
((DoubleList) t).addAll((DoubleList) u);
break;
default:
throw new RuntimeException(cls.getCanonicalName()
+ " can't be combined by default. Only Map/Collection/StringBuilder/Multiset/LongMultiset/Multimap/Sheet/BooleanList ... List are supported");
}
}
}
};
static volatile boolean isListElementDataFieldGettable = true;
static volatile boolean isListElementDataFieldSettable = true;
static final Field listElementDataField;
static final Field listSizeField;
static {
Field tmp = null;
try {
tmp = ArrayList.class.getDeclaredField("elementData");
} catch (Throwable e) {
// ignore.
}
listElementDataField = tmp != null && tmp.getType().equals(Object[].class) ? tmp : null;
if (listElementDataField != null) {
listElementDataField.setAccessible(true);
}
tmp = null;
try {
tmp = ArrayList.class.getDeclaredField("size");
} catch (Throwable e) {
// ignore.
}
listSizeField = tmp != null && tmp.getType().equals(int.class) ? tmp : null;
if (listSizeField != null) {
listSizeField.setAccessible(true);
}
}
final Deque closeHandlers;
final boolean sorted;
final Comparator super T> cmp;;
boolean isClosed = false;
StreamBase(final boolean sorted, final Comparator super T> cmp, final Collection closeHandlers) {
this.closeHandlers = N.isNullOrEmpty(closeHandlers) ? null
: (closeHandlers instanceof LocalArrayDeque ? (LocalArrayDeque) closeHandlers : new LocalArrayDeque<>(closeHandlers));
this.sorted = sorted;
this.cmp = cmp;
}
@Override
public S carry(C action) {
return peek(action);
}
// @Override
// public OT findAny(P predicate) {
// return findFirst(predicate);
// }
@Override
public S slice(final long from, final long to) {
checkArgNotNegative(from, "from");
checkArgNotNegative(to, "to");
checkArgument(to >= from, "'to' can't be less than `from`");
return from == 0 ? limit(to) : skip(from).limit(to - from);
}
@Override
public Stream sliding(int windowSize) {
return sliding(windowSize, 1);
}
@Override
public Stream slidingToList(int windowSize) {
return slidingToList(windowSize, 1);
}
@Override
public S shuffled() {
return shuffled(RAND);
}
@Override
public ImmutableList toImmutableList() {
return ImmutableList.of(toList());
}
@Override
public ImmutableSet toImmutableSet() {
return ImmutableSet.of(toSet());
}
@Override
public String join(final CharSequence delimiter) {
return join(delimiter, "", "");
}
@Override
public void println() {
N.println(sequential().join(", ", "[", "]"));
}
@Override
public boolean isParallel() {
return false;
}
@Override
public S sequential() {
return (S) this;
}
@Override
public S parallel() {
return parallel(DEFAULT_MAX_THREAD_NUM, DEFAULT_SPLITOR);
}
@Override
public S parallel(int maxThreadNum) {
return parallel(maxThreadNum, DEFAULT_SPLITOR);
}
@Override
public S parallel(Splitor splitor) {
return parallel(DEFAULT_MAX_THREAD_NUM, splitor);
}
@Override
public S parallel(final Executor exector) {
return parallel(DEFAULT_MAX_THREAD_NUM, exector);
}
// @Deprecated
// @Override
// public > SS parallelOnly(final Function super S, SS> func) {
// return (SS) parallel().__(func).sequential();
// }
//
// @Deprecated
// @Override
// public > SS parallelOnly(int maxThreadNum, final Function super S, SS> func) {
// return (SS) parallel(maxThreadNum).__(func).sequential();
// }
//
// @Deprecated
// @Override
// public > SS parallelOnly(int maxThreadNum, final Executor exector, final Function super S, SS> func) {
// return (SS) parallel(maxThreadNum, exector).__(func).sequential();
// }
protected int maxThreadNum() {
// throw new UnsupportedOperationException();
// ignore, do nothing if it's sequential stream.
return 1;
}
// @Override
// public S maxThreadNum(int maxThreadNum) {
// // throw new UnsupportedOperationException();
//
// // ignore, do nothing if it's sequential stream.
// return (S) this;
// }
protected Splitor splitor() {
// throw new UnsupportedOperationException();
// ignore, do nothing if it's sequential stream.
return DEFAULT_SPLITOR;
}
// @Override
// public S splitor(Splitor splitor) {
// // throw new UnsupportedOperationException();
//
// // ignore, do nothing if it's sequential stream.
// return (S) this;
// }
protected AsyncExecutor asyncExecutor() {
// throw new UnsupportedOperationException();
// ignore, do nothing if it's sequential stream.
return DEFAULT_ASYNC_EXECUTOR;
}
// @Override
// @SuppressWarnings("rawtypes")
// public SS p_s(Function super S, SS> op) {
// return (SS) this.parallel().__(op).sequential();
// }
//
// @Override
// @SuppressWarnings("rawtypes")
// public SS p_s(int maxThreadNum, Function super S, SS> op) {
// return (SS) this.parallel(maxThreadNum).__(op).sequential();
// }
// @Override
// public Try tried() {
// return Try.of((S) this);
// }
@Override
public synchronized void close() {
if (isClosed) {
return;
}
if (isEmptyCloseHandlers(closeHandlers)) {
isClosed = true;
return;
}
// // Only mark the stream closed if closeHandlers are not empty.
// if (isClosed || N.isNullOrEmpty(closeHandlers)) {
// return;
// }
logger.info("Closing Stream");
isClosed = true;
close(closeHandlers);
}
static void close(final Deque closeHandlers) {
Throwable ex = null;
for (Runnable closeHandler : closeHandlers) {
try {
closeHandler.run();
} catch (Exception e) {
if (ex == null) {
ex = e;
} else {
ex.addSuppressed(e);
}
}
}
if (ex != null) {
throw N.toRuntimeException(ex);
}
}
static void close(final Collection extends IteratorEx>> iters) {
Throwable ex = null;
for (IteratorEx> iter : iters) {
try {
iter.close();
} catch (Exception e) {
if (ex == null) {
ex = e;
} else {
ex.addSuppressed(e);
}
}
}
if (ex != null) {
throw N.toRuntimeException(ex);
}
}
void assertNotClosed() {
if (isClosed) {
throw new IllegalStateException("This stream has been closed");
}
}
void checkIndex(final int index, final int length) {
if (index < 0 || index >= length) {
try {
N.checkIndex(index, length);
} finally {
close();
}
}
}
void checkFromToIndex(final int fromIndex, final int toIndex, final int length) {
if (fromIndex < 0 || fromIndex > toIndex || toIndex > length) {
try {
N.checkFromToIndex(fromIndex, toIndex, length);
} finally {
close();
}
}
}
void checkFromIndexSize(final int fromIndex, final int size, final int length) {
if ((length | fromIndex | size) < 0 || size > length - fromIndex) {
try {
N.checkFromIndexSize(fromIndex, size, length);
} finally {
close();
}
}
}
int checkArgPositive(final int arg, final String argNameOrErrorMsg) {
if (arg <= 0) {
try {
N.checkArgPositive(arg, argNameOrErrorMsg);
} finally {
close();
}
}
return arg;
}
long checkArgPositive(final long arg, final String argNameOrErrorMsg) {
if (arg <= 0) {
try {
N.checkArgPositive(arg, argNameOrErrorMsg);
} finally {
close();
}
}
return arg;
}
int checkArgNotNegative(final int arg, final String argNameOrErrorMsg) {
if (arg < 0) {
try {
N.checkArgNotNegative(arg, argNameOrErrorMsg);
} finally {
close();
}
}
return arg;
}
long checkArgNotNegative(final long arg, final String argNameOrErrorMsg) {
if (arg < 0) {
try {
N.checkArgNotNegative(arg, argNameOrErrorMsg);
} finally {
close();
}
}
return arg;
}
ARG checkArgNotNull(final ARG obj) {
if (obj == null) {
try {
N.checkArgNotNull(obj);
} finally {
close();
}
}
return obj;
}
ARG checkArgNotNull(final ARG obj, final String errorMessage) {
if (obj == null) {
try {
N.checkArgNotNull(obj, errorMessage);
} finally {
close();
}
}
return obj;
}
void checkArgument(boolean b, String errorMessage) {
if (!b) {
try {
N.checkArgument(b, errorMessage);
} finally {
close();
}
}
}
void checkArgument(boolean b, String errorMessageTemplate, int p1) {
if (!b) {
try {
N.checkArgument(b, errorMessageTemplate, p1);
} finally {
close();
}
}
}
void checkArgument(boolean b, String errorMessageTemplate, long p1) {
if (!b) {
try {
N.checkArgument(b, errorMessageTemplate, p1);
} finally {
close();
}
}
}
void checkArgument(boolean b, String errorMessageTemplate, Object p1) {
if (!b) {
try {
N.checkArgument(b, errorMessageTemplate, p1);
} finally {
close();
}
}
}
void checkArgument(boolean b, String errorMessageTemplate, int p1, int p2) {
if (!b) {
try {
N.checkArgument(b, errorMessageTemplate, p1, p2);
} finally {
close();
}
}
}
void checkArgument(boolean b, String errorMessageTemplate, long p1, long p2) {
if (!b) {
try {
N.checkArgument(b, errorMessageTemplate, p1, p2);
} finally {
close();
}
}
}
void checkArgument(boolean b, String errorMessageTemplate, Object p1, Object p2) {
if (!b) {
try {
N.checkArgument(b, errorMessageTemplate, p1, p2);
} finally {
close();
}
}
}
void checkArgument(boolean b, String errorMessageTemplate, Object p1, Object p2, Object p3) {
if (!b) {
try {
N.checkArgument(b, errorMessageTemplate, p1, p2, p3);
} finally {
close();
}
}
}
void checkState(boolean b) {
if (!b) {
try {
N.checkState(b);
} finally {
close();
}
}
}
void checkState(boolean b, String errorMessage) {
if (!b) {
try {
N.checkState(b, errorMessage);
} finally {
close();
}
}
}
void checkState(boolean b, String errorMessageTemplate, int p1) {
if (!b) {
try {
N.checkState(b, errorMessageTemplate, p1);
} finally {
close();
}
}
}
void checkState(boolean b, String errorMessageTemplate, long p1) {
if (!b) {
try {
N.checkState(b, errorMessageTemplate, p1);
} finally {
close();
}
}
}
void checkState(boolean b, String errorMessageTemplate, Object p1) {
if (!b) {
try {
N.checkState(b, errorMessageTemplate, p1);
} finally {
close();
}
}
}
void checkState(boolean b, String errorMessageTemplate, int p1, int p2) {
if (!b) {
try {
N.checkState(b, errorMessageTemplate, p1, p2);
} finally {
close();
}
}
}
void checkState(boolean b, String errorMessageTemplate, long p1, long p2) {
if (!b) {
try {
N.checkState(b, errorMessageTemplate, p1, p2);
} finally {
close();
}
}
}
void checkState(boolean b, String errorMessageTemplate, Object p1, Object p2) {
if (!b) {
try {
N.checkState(b, errorMessageTemplate, p1, p2);
} finally {
close();
}
}
}
void checkState(boolean b, String errorMessageTemplate, Object p1, Object p2, Object p3) {
if (!b) {
try {
N.checkState(b, errorMessageTemplate, p1, p2, p3);
} finally {
close();
}
}
}
int checkMaxThreadNum(int maxThreadNum) {
checkArgument(maxThreadNum > 0, "'maxThreadNum' must not less than 1");
return N.min(maxThreadNum, MAX_THREAD_NUM_PER_OPERATION);
}
Splitor checkSplitor(final Splitor splitor) {
checkArgNotNull(splitor, "splitor");
return splitor;
}
AsyncExecutor createAsyncExecutor(final Executor executor) {
checkArgNotNull(executor, "executor");
return new AsyncExecutor(executor);
}
protected CharStream newStream(final char[] a, final boolean sorted) {
if (this.isParallel()) {
return new ParallelArrayCharStream(a, 0, a.length, sorted, this.maxThreadNum(), this.splitor(), this.asyncExecutor(), closeHandlers);
} else {
return new ArrayCharStream(a, sorted, closeHandlers);
}
}
protected CharStream newStream(final char[] a, final int fromIndex, final int toIndex, final boolean sorted) {
if (this.isParallel()) {
return new ParallelArrayCharStream(a, fromIndex, toIndex, sorted, this.maxThreadNum(), this.splitor(), this.asyncExecutor(), closeHandlers);
} else {
return new ArrayCharStream(a, fromIndex, toIndex, sorted, closeHandlers);
}
}
protected CharStream newStream(final CharIterator iter, final boolean sorted) {
if (this.isParallel()) {
return new ParallelIteratorCharStream(iter, sorted, this.maxThreadNum(), this.splitor(), this.asyncExecutor(), closeHandlers);
} else {
return new IteratorCharStream(iter, sorted, closeHandlers);
}
}
protected ByteStream newStream(final byte[] a, final boolean sorted) {
if (this.isParallel()) {
return new ParallelArrayByteStream(a, 0, a.length, sorted, this.maxThreadNum(), this.splitor(), this.asyncExecutor(), closeHandlers);
} else {
return new ArrayByteStream(a, sorted, closeHandlers);
}
}
protected ByteStream newStream(final byte[] a, final int fromIndex, final int toIndex, final boolean sorted) {
if (this.isParallel()) {
return new ParallelArrayByteStream(a, fromIndex, toIndex, sorted, this.maxThreadNum(), this.splitor(), this.asyncExecutor(), closeHandlers);
} else {
return new ArrayByteStream(a, fromIndex, toIndex, sorted, closeHandlers);
}
}
protected ByteStream newStream(final ByteIterator iter, final boolean sorted) {
if (this.isParallel()) {
return new ParallelIteratorByteStream(iter, sorted, this.maxThreadNum(), this.splitor(), this.asyncExecutor(), closeHandlers);
} else {
return new IteratorByteStream(iter, sorted, closeHandlers);
}
}
protected ShortStream newStream(final short[] a, final boolean sorted) {
if (this.isParallel()) {
return new ParallelArrayShortStream(a, 0, a.length, sorted, this.maxThreadNum(), this.splitor(), this.asyncExecutor(), closeHandlers);
} else {
return new ArrayShortStream(a, sorted, closeHandlers);
}
}
protected ShortStream newStream(final short[] a, final int fromIndex, final int toIndex, final boolean sorted) {
if (this.isParallel()) {
return new ParallelArrayShortStream(a, fromIndex, toIndex, sorted, this.maxThreadNum(), this.splitor(), this.asyncExecutor(), closeHandlers);
} else {
return new ArrayShortStream(a, fromIndex, toIndex, sorted, closeHandlers);
}
}
protected ShortStream newStream(final ShortIterator iter, final boolean sorted) {
if (this.isParallel()) {
return new ParallelIteratorShortStream(iter, sorted, this.maxThreadNum(), this.splitor(), this.asyncExecutor(), closeHandlers);
} else {
return new IteratorShortStream(iter, sorted, closeHandlers);
}
}
protected IntStream newStream(final int[] a, final boolean sorted) {
if (this.isParallel()) {
return new ParallelArrayIntStream(a, 0, a.length, sorted, this.maxThreadNum(), this.splitor(), this.asyncExecutor(), closeHandlers);
} else {
return new ArrayIntStream(a, sorted, closeHandlers);
}
}
protected IntStream newStream(final int[] a, final int fromIndex, final int toIndex, final boolean sorted) {
if (this.isParallel()) {
return new ParallelArrayIntStream(a, fromIndex, toIndex, sorted, this.maxThreadNum(), this.splitor(), this.asyncExecutor(), closeHandlers);
} else {
return new ArrayIntStream(a, fromIndex, toIndex, sorted, closeHandlers);
}
}
protected IntStream newStream(final IntIterator iter, final boolean sorted) {
if (this.isParallel()) {
return new ParallelIteratorIntStream(iter, sorted, this.maxThreadNum(), this.splitor(), this.asyncExecutor(), closeHandlers);
} else {
return new IteratorIntStream(iter, sorted, closeHandlers);
}
}
protected LongStream newStream(final long[] a, final boolean sorted) {
if (this.isParallel()) {
return new ParallelArrayLongStream(a, 0, a.length, sorted, this.maxThreadNum(), this.splitor(), this.asyncExecutor(), closeHandlers);
} else {
return new ArrayLongStream(a, sorted, closeHandlers);
}
}
protected LongStream newStream(final long[] a, final int fromIndex, final int toIndex, final boolean sorted) {
if (this.isParallel()) {
return new ParallelArrayLongStream(a, fromIndex, toIndex, sorted, this.maxThreadNum(), this.splitor(), this.asyncExecutor(), closeHandlers);
} else {
return new ArrayLongStream(a, fromIndex, toIndex, sorted, closeHandlers);
}
}
protected LongStream newStream(final LongIterator iter, final boolean sorted) {
if (this.isParallel()) {
return new ParallelIteratorLongStream(iter, sorted, this.maxThreadNum(), this.splitor(), this.asyncExecutor(), closeHandlers);
} else {
return new IteratorLongStream(iter, sorted, closeHandlers);
}
}
protected FloatStream newStream(final float[] a, final boolean sorted) {
if (this.isParallel()) {
return new ParallelArrayFloatStream(a, 0, a.length, sorted, this.maxThreadNum(), this.splitor(), this.asyncExecutor(), closeHandlers);
} else {
return new ArrayFloatStream(a, sorted, closeHandlers);
}
}
protected FloatStream newStream(final float[] a, final int fromIndex, final int toIndex, final boolean sorted) {
if (this.isParallel()) {
return new ParallelArrayFloatStream(a, fromIndex, toIndex, sorted, this.maxThreadNum(), this.splitor(), this.asyncExecutor(), closeHandlers);
} else {
return new ArrayFloatStream(a, fromIndex, toIndex, sorted, closeHandlers);
}
}
protected FloatStream newStream(final FloatIterator iter, final boolean sorted) {
if (this.isParallel()) {
return new ParallelIteratorFloatStream(iter, sorted, this.maxThreadNum(), this.splitor(), this.asyncExecutor(), closeHandlers);
} else {
return new IteratorFloatStream(iter, sorted, closeHandlers);
}
}
protected DoubleStream newStream(final double[] a, final boolean sorted) {
if (this.isParallel()) {
return new ParallelArrayDoubleStream(a, 0, a.length, sorted, this.maxThreadNum(), this.splitor(), this.asyncExecutor(), closeHandlers);
} else {
return new ArrayDoubleStream(a, sorted, closeHandlers);
}
}
protected DoubleStream newStream(final double[] a, final int fromIndex, final int toIndex, final boolean sorted) {
if (this.isParallel()) {
return new ParallelArrayDoubleStream(a, fromIndex, toIndex, sorted, this.maxThreadNum(), this.splitor(), this.asyncExecutor(), closeHandlers);
} else {
return new ArrayDoubleStream(a, fromIndex, toIndex, sorted, closeHandlers);
}
}
protected DoubleStream newStream(final DoubleIterator iter, final boolean sorted) {
if (this.isParallel()) {
return new ParallelIteratorDoubleStream(iter, sorted, this.maxThreadNum(), this.splitor(), this.asyncExecutor(), closeHandlers);
} else {
return new IteratorDoubleStream(iter, sorted, closeHandlers);
}
}
protected Stream newStream(final E[] a, final boolean sorted, final Comparator super E> comparator) {
return newStream(a, 0, a.length, sorted, comparator);
}
protected Stream newStream(final E[] a, final int fromIndex, final int toIndex, final boolean sorted, final Comparator super E> comparator) {
if (this.isParallel()) {
return new ParallelArrayStream<>(a, fromIndex, toIndex, sorted, comparator, this.maxThreadNum(), this.splitor(), this.asyncExecutor(),
closeHandlers);
} else {
return new ArrayStream<>(a, fromIndex, toIndex, sorted, comparator, closeHandlers);
}
}
protected Stream newStream(final Iterator iter, final boolean sorted, final Comparator super E> comparator) {
if (this.isParallel()) {
return new ParallelIteratorStream<>(iter, sorted, comparator, this.maxThreadNum(), this.splitor(), this.asyncExecutor(), closeHandlers);
} else {
return new IteratorStream<>(iter, sorted, comparator, closeHandlers);
}
}
protected Stream newStream(final Stream s, final boolean sorted, final Comparator super E> comparator) {
if (this.isParallel()) {
return new ParallelIteratorStream<>(s, sorted, comparator, this.maxThreadNum(), this.splitor(), this.asyncExecutor(), closeHandlers);
} else {
return new IteratorStream<>(s, sorted, comparator, closeHandlers);
}
}
static void setError(final Holder errorHolder, Throwable e) {
synchronized (errorHolder) {
if (errorHolder.value() == null) {
errorHolder.setValue(e);
} else {
errorHolder.value().addSuppressed(e);
}
}
}
static void setError(final Holder errorHolder, Throwable e, final MutableBoolean onGoing) {
onGoing.setFalse();
setError(errorHolder, e);
}
static void throwError(final Holder errorHolder, final MutableBoolean onGoing) {
onGoing.setFalse();
synchronized (errorHolder) {
if (errorHolder.value() != null) {
throw N.toRuntimeException(errorHolder.getAndSet(null));
}
}
}
static void complete(final List> futureList, final Holder eHolder) {
if (eHolder.value() != null) {
throw N.toRuntimeException(eHolder.value());
}
try {
for (ContinuableFuture future : futureList) {
future.get();
if (eHolder.value() != null) {
break;
}
}
} catch (InterruptedException | ExecutionException e) {
if (eHolder.value() != null) {
throw N.toRuntimeException(eHolder.value());
}
throw N.toRuntimeException(e);
}
if (eHolder.value() != null) {
throw N.toRuntimeException(eHolder.value());
}
}
static void complette(final List> futureList, final Holder eHolder, E none) throws E {
if (eHolder.value() != null) {
if (eHolder.value() instanceof Exception) {
throw (E) eHolder.value();
} else {
throw N.toRuntimeException(eHolder.value());
}
}
try {
for (ContinuableFuture future : futureList) {
future.get();
if (eHolder.value() != null) {
break;
}
}
} catch (InterruptedException | ExecutionException e) {
if (eHolder.value() != null) {
if (eHolder.value() instanceof Exception) {
throw (E) eHolder.value();
} else {
throw N.toRuntimeException(eHolder.value());
}
}
throw N.toRuntimeException(e);
}
if (eHolder.value() != null) {
if (eHolder.value() instanceof Exception) {
throw (E) eHolder.value();
} else {
throw N.toRuntimeException(eHolder.value());
}
}
}
static int calculateQueueSize(int len) {
return N.min(MAX_QUEUE_SIZE, len * DEFAULT_QUEUE_SIZE_PER_ITERATOR);
}
static boolean isSameComparator(Comparator> a, Comparator> b) {
if (a == b) {
return true;
} else if (a == null) {
return defaultComparator.containsValue(b);
} else if (b == null) {
return defaultComparator.containsValue(a);
} else {
return (a == NATURAL_COMPARATOR && defaultComparator.containsValue(b)) || (b == NATURAL_COMPARATOR && defaultComparator.containsValue(a));
}
}
static int toInt(long max) {
return max > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) max;
}
static CharIteratorEx charIterator(final ObjIteratorEx iter) {
return CharIteratorEx.from(iter);
}
static ByteIteratorEx byteIterator(final ObjIteratorEx iter) {
return ByteIteratorEx.from(iter);
}
static ShortIteratorEx shortIterator(final ObjIteratorEx iter) {
return ShortIteratorEx.from(iter);
}
static IntIteratorEx intIterator(final ObjIteratorEx iter) {
return IntIteratorEx.from(iter);
}
static LongIteratorEx longIterator(final ObjIteratorEx iter) {
return LongIteratorEx.from(iter);
}
static FloatIteratorEx floatIterator(final ObjIteratorEx iter) {
return FloatIteratorEx.from(iter);
}
static DoubleIteratorEx doubleIterator(final ObjIteratorEx iter) {
return DoubleIteratorEx.from(iter);
}
static Runnable wrapCloseHandlers(final Runnable closeHandler) {
if (closeHandler == null || closeHandler == EMPTY_CLOSE_HANDLER) {
return EMPTY_CLOSE_HANDLER;
}
return new Runnable() {
private volatile boolean isClosed = false;
@Override
public void run() {
if (isClosed) {
return;
}
isClosed = true;
closeHandler.run();
}
};
}
static Runnable newCloseHandle(final AutoCloseable closeable) {
return Fn.closeQuietly(closeable);
}
static Runnable newCloseHandler(final Collection extends StreamBase, ?, ?, ?, ?, ?, ?, ?, ?>> c) {
if (N.isNullOrEmpty(c)) {
return EMPTY_CLOSE_HANDLER;
}
boolean allEmptyHandlers = true;
for (StreamBase, ?, ?, ?, ?, ?, ?, ?, ?> s : c) {
if (!isEmptyCloseHandlers(s.closeHandlers)) {
allEmptyHandlers = false;
break;
}
}
if (allEmptyHandlers) {
return EMPTY_CLOSE_HANDLER;
}
return new Runnable() {
@Override
public void run() {
RuntimeException runtimeException = null;
for (StreamBase, ?, ?, ?, ?, ?, ?, ?, ?> s : c) {
if (isEmptyCloseHandlers(s.closeHandlers)) {
continue;
}
try {
s.close();
} catch (Exception throwable) {
if (runtimeException == null) {
runtimeException = N.toRuntimeException(throwable);
} else {
runtimeException.addSuppressed(throwable);
}
}
}
if (runtimeException != null) {
throw runtimeException;
}
}
};
}
static Deque mergeCloseHandlers(final StreamBase, ?, ?, ?, ?, ?, ?, ?, ?> stream, final Deque closeHandlers) {
return mergeCloseHandlers(stream.closeHandlers, closeHandlers);
}
static Deque mergeCloseHandlers(final Deque closeHandlersA, final Deque closeHandlersB) {
if (isEmptyCloseHandlers(closeHandlersA) && closeHandlersB instanceof LocalArrayDeque) {
return closeHandlersB;
} else if (closeHandlersA instanceof LocalArrayDeque && isEmptyCloseHandlers(closeHandlersB)) {
return closeHandlersA;
} else if (isEmptyCloseHandlers(closeHandlersA) && isEmptyCloseHandlers(closeHandlersB)) {
return null;
}
final Deque newCloseHandlers = new LocalArrayDeque<>();
if (!isEmptyCloseHandlers(closeHandlersA)) {
newCloseHandlers.addAll(closeHandlersA);
}
if (!isEmptyCloseHandlers(closeHandlersB)) {
newCloseHandlers.addAll(closeHandlersB);
}
return newCloseHandlers;
}
static boolean isEmptyCloseHandlers(final Deque closeHandlers) {
return N.isNullOrEmpty(closeHandlers) || (closeHandlers.size() == 1 && closeHandlers.getFirst() == EMPTY_CLOSE_HANDLER);
}
static Object hashKey(Object obj) {
return obj == null ? NONE : (obj.getClass().isArray() ? Wrapper.of(obj) : obj);
}
static T[] toArray(Collection c) {
if (isListElementDataFieldGettable && listElementDataField != null && c instanceof ArrayList) {
try {
return (T[]) listElementDataField.get(c);
} catch (Throwable e) {
// ignore;
isListElementDataFieldGettable = false;
}
}
return (T[]) c.toArray();
}
@SafeVarargs
static List createList(final T... a) {
if (N.isNullOrEmpty(a)) {
return new ArrayList<>();
}
if (isListElementDataFieldSettable && listElementDataField != null && listSizeField != null) {
final List list = new ArrayList<>();
try {
listElementDataField.set(list, a);
listSizeField.set(list, a.length);
return list;
} catch (Throwable e) {
// ignore;
isListElementDataFieldSettable = false;
}
}
return N.asList(a);
}
static int sum(final char[] a) {
if (a == null || a.length == 0) {
return 0;
}
return sum(a, 0, a.length);
}
static int sum(final char[] a, final int from, final int to) {
long sum = 0;
for (int i = from; i < to; i++) {
sum += a[i];
}
return N.toIntExact(sum);
}
static int sum(final byte[] a) {
if (a == null || a.length == 0) {
return 0;
}
return sum(a, 0, a.length);
}
static int sum(final byte[] a, final int from, final int to) {
long sum = 0;
for (int i = from; i < to; i++) {
sum += a[i];
}
return N.toIntExact(sum);
}
static int sum(final short[] a) {
if (a == null || a.length == 0) {
return 0;
}
return sum(a, 0, a.length);
}
static int sum(final short[] a, final int from, final int to) {
long sum = 0;
for (int i = from; i < to; i++) {
sum += a[i];
}
return N.toIntExact(sum);
}
static int sum(final int[] a) {
if (a == null || a.length == 0) {
return 0;
}
return sum(a, 0, a.length);
}
static int sum(final int[] a, final int from, final int to) {
long sum = 0;
for (int i = from; i < to; i++) {
sum += a[i];
}
return N.toIntExact(sum);
}
static long sum(final long[] a) {
if (a == null || a.length == 0) {
return 0L;
}
return sum(a, 0, a.length);
}
static long sum(final long[] a, final int from, final int to) {
long sum = 0;
for (int i = from; i < to; i++) {
sum += a[i];
}
return sum;
}
static double sum(final float[] a) {
if (a == null || a.length == 0) {
return 0d;
}
return sum(a, 0, a.length);
}
static double sum(final float[] a, final int from, final int to) {
return FloatStream.of(a, from, to).sum();
}
static double sum(final double[] a) {
if (a == null || a.length == 0) {
return 0d;
}
return sum(a, 0, a.length);
}
static double sum(final double[] a, final int from, final int to) {
return DoubleStream.of(a, from, to).sum();
}
static final class LocalArrayDeque extends ArrayDeque {
private static final long serialVersionUID = -97425473105100734L;
public LocalArrayDeque() {
super();
}
public LocalArrayDeque(int initialCapacity) {
super(initialCapacity);
}
public LocalArrayDeque(Collection extends T> c) {
super(c);
}
}
}