com.landawn.abacus.util.Array Maven / Gradle / Ivy
Show all versions of abacus-android Show documentation
/*
* Copyright (c) 2015, 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.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.RandomAccess;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import com.landawn.abacus.annotation.NullSafe;
/**
*
* @since 0.8
*
* @author Haiyang Li
*
* @see java.lang.reflect.Array
*/
public final class Array {
static final AsyncExecutor parallelSortExecutor = new AsyncExecutor(64, 300L, TimeUnit.SECONDS);
static volatile int CPU_CORES = IOUtil.CPU_CORES;
static final int MIN_ARRAY_SORT_GRAN = 8192;
static final int BINARYSEARCH_THRESHOLD = 64;
private Array() {
}
public static T newInstance(final Class> componentType, final int length) throws NegativeArraySizeException {
if (length == 0) {
Object result = N.CLASS_EMPTY_ARRAY.get(componentType);
if (result == null) {
result = java.lang.reflect.Array.newInstance(componentType, length);
N.CLASS_EMPTY_ARRAY.put(componentType, result);
}
return (T) result;
}
return (T) java.lang.reflect.Array.newInstance(componentType, length);
}
@SafeVarargs
public static T newInstance(final Class> componentType, final int... dimensions) throws IllegalArgumentException, NegativeArraySizeException {
return (T) java.lang.reflect.Array.newInstance(componentType, dimensions);
}
public static int getLength(final Object array) throws IllegalArgumentException {
return java.lang.reflect.Array.getLength(array);
}
public static T get(final Object array, final int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
return (T) java.lang.reflect.Array.get(array, index);
}
public static boolean getBoolean(final Object array, final int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
return java.lang.reflect.Array.getBoolean(array, index);
}
public static byte getByte(final Object array, final int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
return java.lang.reflect.Array.getByte(array, index);
}
public static char getChar(final Object array, final int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
return java.lang.reflect.Array.getChar(array, index);
}
public static short getShort(final Object array, final int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
return java.lang.reflect.Array.getShort(array, index);
}
public static int getInt(final Object array, final int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
return java.lang.reflect.Array.getInt(array, index);
}
public static long getLong(final Object array, final int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
return java.lang.reflect.Array.getLong(array, index);
}
public static float getFloat(final Object array, final int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
return java.lang.reflect.Array.getFloat(array, index);
}
public static double getDouble(final Object array, final int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
return java.lang.reflect.Array.getDouble(array, index);
}
public static void set(final Object array, final int index, final Object value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
java.lang.reflect.Array.set(array, index, value);
}
public static void setBoolean(final Object array, final int index, final boolean z) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
java.lang.reflect.Array.setBoolean(array, index, z);
}
public static void setByte(final Object array, final int index, final byte b) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
java.lang.reflect.Array.setByte(array, index, b);
}
public static void setChar(final Object array, final int index, final char c) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
java.lang.reflect.Array.setChar(array, index, c);
}
public static void setShort(final Object array, final int index, final short s) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
java.lang.reflect.Array.setShort(array, index, s);
}
public static void setInt(final Object array, final int index, final int i) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
java.lang.reflect.Array.setInt(array, index, i);
}
public static void setLong(final Object array, final int index, final long l) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
java.lang.reflect.Array.setLong(array, index, l);
}
public static void setFloat(final Object array, final int index, final float f) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
java.lang.reflect.Array.setFloat(array, index, f);
}
public static void setDouble(final Object array, final int index, final double d) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
java.lang.reflect.Array.setDouble(array, index, d);
}
/**
* Returns a fixed-size list backed by the specified array if it's not null or empty, otherwise an immutable empty list is returned.
*
* @param a
* @return
* @see Arrays#asList(Object...)
*/
@SafeVarargs
@NullSafe
public static List asList(T... a) {
return N.isNullOrEmpty(a) ? N. emptyList() : Arrays.asList(a);
}
/**
* Returns the input array
*
* @param a
* @return
*/
@SafeVarargs
public static boolean[] of(final boolean... a) {
return a;
}
/**
* Returns the input array
*
* @param a
* @return
*/
@SafeVarargs
public static char[] of(final char... a) {
return a;
}
/**
* Returns the input array
*
* @param a
* @return
*/
@SafeVarargs
public static byte[] of(final byte... a) {
return a;
}
/**
* Returns the input array
*
* @param a
* @return
*/
@SafeVarargs
public static short[] of(final short... a) {
return a;
}
/**
* Returns the input array
*
* @param a
* @return
*/
@SafeVarargs
public static int[] of(final int... a) {
return a;
}
/**
* Returns the input array
*
* @param a
* @return
*/
@SafeVarargs
public static long[] of(final long... a) {
return a;
}
/**
* Returns the input array
*
* @param a
* @return
*/
@SafeVarargs
public static float[] of(final float... a) {
return a;
}
/**
* Returns the input array
*
* @param a
* @return
*/
@SafeVarargs
public static double[] of(final double... a) {
return a;
}
/**
* Returns the input array
*
* @param a
* @return
*/
@SafeVarargs
public static String[] of(final String... a) {
return a;
}
// /**
// * Returns the input array
// *
// * @param a
// * @return
// */
// @SafeVarargs
// public static BigInteger[] of(final BigInteger... a) {
// return a;
// }
//
// /**
// * Returns the input array
// *
// * @param a
// * @return
// */
// @SafeVarargs
// public static BigDecimal[] of(final BigDecimal... a) {
// return a;
// }
//
// /**
// * Returns the input array
// *
// * @param a
// * @return
// */
// public static > T[] of(final T... a) {
// return a;
// }
//
// /**
// * Returns the input array
// *
// * @param a
// * @return
// */
// public static T[] of(final T... a) {
// return a;
// }
//
// /**
// * Returns the input array
// *
// * @param a
// * @return
// */
// public static T[] of(final T... a) {
// return a;
// }
//
// /**
// * Returns the input array
// *
// * @param a
// * @return
// */
// public static T[] of(final T... a) {
// return a;
// }
//
// /**
// * Returns the input array
// *
// * @param a
// * @return
// */
// public static > T[] of(final T... a) {
// return a;
// }
//
// /**
// * Returns the input array
// *
// * @param a
// * @return
// */
// @SuppressWarnings("rawtypes")
// public static Class[] of(final Class... a) {
// return a;
// }
//
// /**
// * Returns the input array
// *
// * @param a
// * @return
// */
// public static T[] of(final T... a) {
// return a;
// }
//
// /**
// * Returns the input array
// *
// * @param a
// * @return
// */
// public static T[] of(final T... a) {
// return a;
// }
//
// /**
// * Returns the input array
// *
// * @param a
// * @return
// */
// public static T[] of(final T... a) {
// return a;
// }
//
// /**
// * Returns the input array
// *
// * @param a
// * @return
// */
// public static > T[] of(final T... a) {
// return a;
// }
//
// /**
// * Returns the input array
// *
// * @param a
// * @return
// */
// public static > T[] of(final T... a) {
// return a;
// }
//
// /**
// * Returns the input array
// *
// * @param a
// * @return
// */
// public static > T[] of(final T... a) {
// return a;
// }
//
// /**
// * Returns the input array
// *
// * @param a
// * @return
// */
// public static > T[] of(final T... a) {
// return a;
// }
//
// /**
// * Returns the input array
// *
// * @param a
// * @return
// */
// public static > T[] of(final T... a) {
// return a;
// }
// // Only for Java 8. it's ambiguous in the Java version before 8.
// /**
// * Returns the input array
// *
// * @param a
// * @return
// */
// public static T[] of(final T... a) {
// return a;
// }
public static char[] range(char startInclusive, final char endExclusive) {
if (startInclusive >= endExclusive) {
return N.EMPTY_CHAR_ARRAY;
}
final char[] a = new char[endExclusive * 1 - startInclusive];
for (int i = 0, len = a.length; i < len; i++) {
a[i] = startInclusive++;
}
return a;
}
public static byte[] range(byte startInclusive, final byte endExclusive) {
if (startInclusive >= endExclusive) {
return N.EMPTY_BYTE_ARRAY;
}
final byte[] a = new byte[endExclusive * 1 - startInclusive];
for (int i = 0, len = a.length; i < len; i++) {
a[i] = startInclusive++;
}
return a;
}
public static short[] range(short startInclusive, final short endExclusive) {
if (startInclusive >= endExclusive) {
return N.EMPTY_SHORT_ARRAY;
}
final short[] a = new short[endExclusive * 1 - startInclusive];
for (int i = 0, len = a.length; i < len; i++) {
a[i] = startInclusive++;
}
return a;
}
public static int[] range(int startInclusive, final int endExclusive) {
if (startInclusive >= endExclusive) {
return N.EMPTY_INT_ARRAY;
}
if (endExclusive * 1L - startInclusive > Integer.MAX_VALUE) {
throw new IllegalArgumentException("overflow");
}
final int[] a = new int[endExclusive - startInclusive];
for (int i = 0, len = a.length; i < len; i++) {
a[i] = startInclusive++;
}
return a;
}
public static long[] range(long startInclusive, final long endExclusive) {
if (startInclusive >= endExclusive) {
return N.EMPTY_LONG_ARRAY;
}
if (endExclusive - startInclusive < 0 || endExclusive - startInclusive > Integer.MAX_VALUE) {
throw new IllegalArgumentException("overflow");
}
final long[] a = new long[(int) (endExclusive - startInclusive)];
for (int i = 0, len = a.length; i < len; i++) {
a[i] = startInclusive++;
}
return a;
}
// // Doesn't work as expected due to precision issue. "3.3d - 1.1d != 2.2d". Refer to: https://en.wikipedia.org/wiki/IEEE_floating_point
// // http://stackoverflow.com/questions/15625556/java-adding-and-subtracting-doubles-are-giving-strange-results
// static float[] range(float startInclusive, final float endExclusive) {
// if (endExclusive == startInclusive) {
// return N.EMPTY_FLOAT_ARRAY;
// }
//
// int tmp = (int) (endExclusive - startInclusive);
// final float[] a = new float[(startInclusive + tmp == endExclusive) ? tmp : tmp + 1];
//
// for (int i = 0, len = a.length; i < len; i++) {
// a[i] = startInclusive++;
// }
//
// return a;
// }
//
// // Doesn't work as expected due to precision issue. "3.3d - 1.1d != 2.2d". Refer to: https://en.wikipedia.org/wiki/IEEE_floating_point
// // http://stackoverflow.com/questions/15625556/java-adding-and-subtracting-doubles-are-giving-strange-results
// static double[] range(double startInclusive, final double endExclusive) {
// if (endExclusive == startInclusive) {
// return N.EMPTY_DOUBLE_ARRAY;
// }
//
// int tmp = (int) (endExclusive - startInclusive);
// final double[] a = new double[(startInclusive + tmp == endExclusive) ? tmp : tmp + 1];
//
// for (int i = 0, len = a.length; i < len; i++) {
// a[i] = startInclusive++;
// }
//
// return a;
// }
public static char[] range(char startInclusive, final char endExclusive, final int by) {
if (by == 0) {
throw new IllegalArgumentException("The input parameter 'by' can't be zero");
}
if (endExclusive == startInclusive || endExclusive > startInclusive != by > 0) {
return N.EMPTY_CHAR_ARRAY;
}
// if (endExclusive > startInclusive != by > 0) {
// throw new IllegalArgumentException(
// "The input 'startInclusive' (" + startInclusive + ") and 'endExclusive' (" + endExclusive + ") are not consistent with by (" + by + ").");
// }
final int len = (endExclusive * 1 - startInclusive) / by + ((endExclusive * 1 - startInclusive) % by == 0 ? 0 : 1);
final char[] a = new char[len];
for (int i = 0; i < len; i++, startInclusive += by) {
a[i] = startInclusive;
}
return a;
}
public static byte[] range(byte startInclusive, final byte endExclusive, final byte by) {
if (by == 0) {
throw new IllegalArgumentException("The input parameter 'by' can't be zero");
}
if (endExclusive == startInclusive || endExclusive > startInclusive != by > 0) {
return N.EMPTY_BYTE_ARRAY;
}
// if (endExclusive > startInclusive != by > 0) {
// throw new IllegalArgumentException(
// "The input 'startInclusive' (" + startInclusive + ") and 'endExclusive' (" + endExclusive + ") are not consistent with by (" + by + ").");
// }
final int len = (endExclusive * 1 - startInclusive) / by + ((endExclusive * 1 - startInclusive) % by == 0 ? 0 : 1);
final byte[] a = new byte[len];
for (int i = 0; i < len; i++, startInclusive += by) {
a[i] = startInclusive;
}
return a;
}
public static short[] range(short startInclusive, final short endExclusive, final short by) {
if (by == 0) {
throw new IllegalArgumentException("The input parameter 'by' can't be zero");
}
if (endExclusive == startInclusive || endExclusive > startInclusive != by > 0) {
return N.EMPTY_SHORT_ARRAY;
}
// if (endExclusive > startInclusive != by > 0) {
// throw new IllegalArgumentException(
// "The input 'startInclusive' (" + startInclusive + ") and 'endExclusive' (" + endExclusive + ") are not consistent with by (" + by + ").");
// }
final int len = (endExclusive * 1 - startInclusive) / by + ((endExclusive * 1 - startInclusive) % by == 0 ? 0 : 1);
final short[] a = new short[len];
for (int i = 0; i < len; i++, startInclusive += by) {
a[i] = startInclusive;
}
return a;
}
public static int[] range(int startInclusive, final int endExclusive, final int by) {
if (by == 0) {
throw new IllegalArgumentException("The input parameter 'by' can't be zero");
}
if (endExclusive == startInclusive || endExclusive > startInclusive != by > 0) {
return N.EMPTY_INT_ARRAY;
}
// if (endExclusive > startInclusive != by > 0) {
// throw new IllegalArgumentException(
// "The input 'startInclusive' (" + startInclusive + ") and 'endExclusive' (" + endExclusive + ") are not consistent with by (" + by + ").");
// }
final long len = (endExclusive * 1L - startInclusive) / by + ((endExclusive * 1L - startInclusive) % by == 0 ? 0 : 1);
if (len > Integer.MAX_VALUE) {
throw new IllegalArgumentException("overflow");
}
final int[] a = new int[(int) len];
for (int i = 0; i < len; i++, startInclusive += by) {
a[i] = startInclusive;
}
return a;
}
public static long[] range(long startInclusive, final long endExclusive, final long by) {
if (by == 0) {
throw new IllegalArgumentException("The input parameter 'by' can't be zero");
}
if (endExclusive == startInclusive || endExclusive > startInclusive != by > 0) {
return N.EMPTY_LONG_ARRAY;
}
// if (endExclusive > startInclusive != by > 0) {
// throw new IllegalArgumentException(
// "The input 'startInclusive' (" + startInclusive + ") and 'endExclusive' (" + endExclusive + ") are not consistent with by (" + by + ").");
// }
long len = 0;
if ((by > 0 && endExclusive - startInclusive < 0) || (by < 0 && startInclusive - endExclusive < 0)) {
final BigInteger m = BigInteger.valueOf(endExclusive).subtract(BigInteger.valueOf(startInclusive)).divide(BigInteger.valueOf(by));
if (m.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0) {
throw new IllegalArgumentException("overflow");
}
len = m.multiply(BigInteger.valueOf(by)).add(BigInteger.valueOf(startInclusive)).equals(BigInteger.valueOf(endExclusive)) ? m.longValue()
: m.longValue() + 1;
} else {
len = (endExclusive - startInclusive) / by + ((endExclusive - startInclusive) % by == 0 ? 0 : 1);
}
if (len > Integer.MAX_VALUE) {
throw new IllegalArgumentException("overflow");
}
final long[] a = new long[(int) len];
for (int i = 0; i < len; i++, startInclusive += by) {
a[i] = startInclusive;
}
return a;
}
// // Doesn't work as expected due to precision issue. "3.3d - 1.1d != 2.2d". Refer to: https://en.wikipedia.org/wiki/IEEE_floating_point
// // http://stackoverflow.com/questions/15625556/java-adding-and-subtracting-doubles-are-giving-strange-results
// static float[] range(float startInclusive, final float endExclusive, final float by) {
// if (by == 0) {
// throw new IllegalArgumentException("The input parameter 'by' can't be zero");
// }
//
// if (endExclusive == startInclusive) {
// return N.EMPTY_FLOAT_ARRAY;
// }
//
// if (endExclusive > startInclusive != by > 0) {
// throw new IllegalArgumentException(
// "The input 'startInclusive' (" + startInclusive + ") and 'endExclusive' (" + endExclusive + ") are not consistent with by (" + by + ").");
// }
//
// final int tmp = (int) ((endExclusive - startInclusive) / by);
// final int len = startInclusive + (tmp * by) == endExclusive ? tmp : tmp + 1;
// final float[] a = new float[len];
//
// for (int i = 0; i < len; i++, startInclusive += by) {
// a[i] = startInclusive;
// }
//
// return a;
// }
//
// // Doesn't work as expected due to precision issue. "3.3d - 1.1d != 2.2d". Refer to: https://en.wikipedia.org/wiki/IEEE_floating_point
// // http://stackoverflow.com/questions/15625556/java-adding-and-subtracting-doubles-are-giving-strange-results
// static double[] range(double startInclusive, final double endExclusive, final double by) {
// if (by == 0) {
// throw new IllegalArgumentException("The input parameter 'by' can't be zero");
// }
//
// if (endExclusive == startInclusive) {
// return N.EMPTY_DOUBLE_ARRAY;
// }
//
// if (endExclusive > startInclusive != by > 0) {
// throw new IllegalArgumentException(
// "The input 'startInclusive' (" + startInclusive + ") and 'endExclusive' (" + endExclusive + ") are not consistent with by (" + by + ").");
// }
//
// final int tmp = (int) ((endExclusive - startInclusive) / by);
// final int len = startInclusive + (tmp * by) == endExclusive ? tmp : tmp + 1;
// final double[] a = new double[len];
//
// for (int i = 0; i < len; i++, startInclusive += by) {
// a[i] = startInclusive;
// }
//
// return a;
// }
public static char[] rangeClosed(char startInclusive, final char endInclusive) {
if (startInclusive > endInclusive) {
return N.EMPTY_CHAR_ARRAY;
} else if (startInclusive == endInclusive) {
return Array.of(startInclusive);
}
final char[] a = new char[endInclusive * 1 - startInclusive + 1];
for (int i = 0, len = a.length; i < len; i++) {
a[i] = startInclusive++;
}
return a;
}
public static byte[] rangeClosed(byte startInclusive, final byte endInclusive) {
if (startInclusive > endInclusive) {
return N.EMPTY_BYTE_ARRAY;
} else if (startInclusive == endInclusive) {
return Array.of(startInclusive);
}
final byte[] a = new byte[endInclusive * 1 - startInclusive + 1];
for (int i = 0, len = a.length; i < len; i++) {
a[i] = startInclusive++;
}
return a;
}
public static short[] rangeClosed(short startInclusive, final short endInclusive) {
if (startInclusive > endInclusive) {
return N.EMPTY_SHORT_ARRAY;
} else if (startInclusive == endInclusive) {
return Array.of(startInclusive);
}
final short[] a = new short[endInclusive * 1 - startInclusive + 1];
for (int i = 0, len = a.length; i < len; i++) {
a[i] = startInclusive++;
}
return a;
}
public static int[] rangeClosed(int startInclusive, final int endInclusive) {
if (startInclusive > endInclusive) {
return N.EMPTY_INT_ARRAY;
} else if (startInclusive == endInclusive) {
return Array.of(startInclusive);
}
if (endInclusive * 1L - startInclusive + 1 > Integer.MAX_VALUE) {
throw new IllegalArgumentException("overflow");
}
final int[] a = new int[endInclusive - startInclusive + 1];
for (int i = 0, len = a.length; i < len; i++) {
a[i] = startInclusive++;
}
return a;
}
public static long[] rangeClosed(long startInclusive, final long endInclusive) {
if (startInclusive > endInclusive) {
return N.EMPTY_LONG_ARRAY;
} else if (startInclusive == endInclusive) {
return Array.of(startInclusive);
}
if (endInclusive - startInclusive + 1 <= 0 || endInclusive - startInclusive + 1 > Integer.MAX_VALUE) {
throw new IllegalArgumentException("overflow");
}
final long[] a = new long[(int) (endInclusive - startInclusive + 1)];
for (int i = 0, len = a.length; i < len; i++) {
a[i] = startInclusive++;
}
return a;
}
// // Doesn't work as expected due to precision issue. "3.3d - 1.1d != 2.2d". Refer to: https://en.wikipedia.org/wiki/IEEE_floating_point
// // http://stackoverflow.com/questions/15625556/java-adding-and-subtracting-doubles-are-giving-strange-results
// static float[] rangeClosed(float startInclusive, final float endInclusive) {
// final float[] a = new float[(int) (endInclusive - startInclusive) + 1];
//
// for (int i = 0, len = a.length; i < len; i++) {
// a[i] = startInclusive++;
// }
//
// return a;
// }
//
// // Doesn't work as expected due to precision issue. "3.3d - 1.1d != 2.2d". Refer to: https://en.wikipedia.org/wiki/IEEE_floating_point
// // http://stackoverflow.com/questions/15625556/java-adding-and-subtracting-doubles-are-giving-strange-results
// static double[] rangeClosed(double startInclusive, final double endInclusive) {
// final double[] a = new double[(int) (endInclusive - startInclusive) + 1];
//
// for (int i = 0, len = a.length; i < len; i++) {
// a[i] = startInclusive++;
// }
//
// return a;
// }
public static char[] rangeClosed(char startInclusive, final char endInclusive, final int by) {
if (by == 0) {
throw new IllegalArgumentException("The input parameter 'by' can't be zero");
}
if (endInclusive == startInclusive) {
return new char[] { startInclusive };
} else if (endInclusive > startInclusive != by > 0) {
return N.EMPTY_CHAR_ARRAY;
}
// if (endInclusive > startInclusive != by > 0) {
// throw new IllegalArgumentException(
// "The input 'startInclusive' (" + startInclusive + ") and 'endInclusive' (" + endInclusive + ") are not consistent with by (" + by + ").");
// }
final int len = (endInclusive * 1 - startInclusive) / by + 1;
final char[] a = new char[len];
for (int i = 0; i < len; i++, startInclusive += by) {
a[i] = startInclusive;
}
return a;
}
public static byte[] rangeClosed(byte startInclusive, final byte endInclusive, final byte by) {
if (by == 0) {
throw new IllegalArgumentException("The input parameter 'by' can't be zero");
}
if (endInclusive == startInclusive) {
return new byte[] { startInclusive };
} else if (endInclusive > startInclusive != by > 0) {
return N.EMPTY_BYTE_ARRAY;
}
// if (endInclusive > startInclusive != by > 0) {
// throw new IllegalArgumentException(
// "The input 'startInclusive' (" + startInclusive + ") and 'endInclusive' (" + endInclusive + ") are not consistent with by (" + by + ").");
// }
final int len = (endInclusive * 1 - startInclusive) / by + 1;
final byte[] a = new byte[len];
for (int i = 0; i < len; i++, startInclusive += by) {
a[i] = startInclusive;
}
return a;
}
public static short[] rangeClosed(short startInclusive, final short endInclusive, final short by) {
if (by == 0) {
throw new IllegalArgumentException("The input parameter 'by' can't be zero");
}
if (endInclusive == startInclusive) {
return new short[] { startInclusive };
} else if (endInclusive > startInclusive != by > 0) {
return N.EMPTY_SHORT_ARRAY;
}
// if (endInclusive > startInclusive != by > 0) {
// throw new IllegalArgumentException(
// "The input 'startInclusive' (" + startInclusive + ") and 'endInclusive' (" + endInclusive + ") are not consistent with by (" + by + ").");
// }
final int len = (endInclusive * 1 - startInclusive) / by + 1;
final short[] a = new short[len];
for (int i = 0; i < len; i++, startInclusive += by) {
a[i] = startInclusive;
}
return a;
}
public static int[] rangeClosed(int startInclusive, final int endInclusive, final int by) {
if (by == 0) {
throw new IllegalArgumentException("The input parameter 'by' can't be zero");
}
if (endInclusive == startInclusive) {
return new int[] { startInclusive };
} else if (endInclusive > startInclusive != by > 0) {
return N.EMPTY_INT_ARRAY;
}
// if (endInclusive > startInclusive != by > 0) {
// throw new IllegalArgumentException(
// "The input 'startInclusive' (" + startInclusive + ") and 'endInclusive' (" + endInclusive + ") are not consistent with by (" + by + ").");
// }
final long len = (endInclusive * 1L - startInclusive) / by + 1;
if (len > Integer.MAX_VALUE) {
throw new IllegalArgumentException("overflow");
}
final int[] a = new int[(int) len];
for (int i = 0; i < len; i++, startInclusive += by) {
a[i] = startInclusive;
}
return a;
}
public static long[] rangeClosed(long startInclusive, final long endInclusive, final long by) {
if (by == 0) {
throw new IllegalArgumentException("The input parameter 'by' can't be zero");
}
if (endInclusive == startInclusive) {
return new long[] { startInclusive };
} else if (endInclusive > startInclusive != by > 0) {
return N.EMPTY_LONG_ARRAY;
}
// if (endInclusive > startInclusive != by > 0) {
// throw new IllegalArgumentException(
// "The input 'startInclusive' (" + startInclusive + ") and 'endInclusive' (" + endInclusive + ") are not consistent with by (" + by + ").");
// }
long len = 0;
if ((by > 0 && endInclusive - startInclusive < 0) || (by < 0 && startInclusive - endInclusive < 0) || ((endInclusive - startInclusive) / by + 1 <= 0)) {
final BigInteger m = BigInteger.valueOf(endInclusive).subtract(BigInteger.valueOf(startInclusive)).divide(BigInteger.valueOf(by));
if (m.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0) {
throw new IllegalArgumentException("overflow");
}
len = m.longValue() + 1;
} else {
len = (endInclusive - startInclusive) / by + 1;
}
if (len > Integer.MAX_VALUE) {
throw new IllegalArgumentException("overflow");
}
final long[] a = new long[(int) len];
for (int i = 0; i < len; i++, startInclusive += by) {
a[i] = startInclusive;
}
return a;
}
// // Doesn't work as expected due to precision issue. "3.3d - 1.1d != 2.2d". Refer to: https://en.wikipedia.org/wiki/IEEE_floating_point
// // http://stackoverflow.com/questions/15625556/java-adding-and-subtracting-doubles-are-giving-strange-results
// static float[] rangeClosed(float startInclusive, final float endExclusive, final float by) {
// if (by == 0) {
// throw new IllegalArgumentException("The input parameter 'by' can't be zero");
// }
//
// if (endExclusive == startInclusive) {
// return new float[] { startInclusive };
// }
//
// if (endExclusive > startInclusive != by > 0) {
// throw new IllegalArgumentException(
// "The input 'startInclusive' (" + startInclusive + ") and 'endExclusive' (" + endExclusive + ") are not consistent with by (" + by + ").");
// }
//
// final int len = (int) (((double) endExclusive - (double) startInclusive) / by) + 1;
// final float[] a = new float[len];
//
// for (int i = 0; i < len; i++, startInclusive += by) {
// a[i] = startInclusive;
// }
//
// return a;
// }
//
// // Doesn't work as expected due to precision issue. "3.3d - 1.1d != 2.2d". Refer to: https://en.wikipedia.org/wiki/IEEE_floating_point
// // http://stackoverflow.com/questions/15625556/java-adding-and-subtracting-doubles-are-giving-strange-results
// static double[] rangeClosed(double startInclusive, final double endExclusive, final double by) {
// if (by == 0) {
// throw new IllegalArgumentException("The input parameter 'by' can't be zero");
// }
//
// if (endExclusive == startInclusive) {
// return new double[] { startInclusive };
// }
//
// if (endExclusive > startInclusive != by > 0) {
// throw new IllegalArgumentException(
// "The input 'startInclusive' (" + startInclusive + ") and 'endExclusive' (" + endExclusive + ") are not consistent with by (" + by + ").");
// }
//
// final int len = (int) ((endExclusive - startInclusive) / by) + 1;
// final double[] a = new double[len];
//
// for (int i = 0; i < len; i++, startInclusive += by) {
// a[i] = startInclusive;
// }
//
// return a;
// }
public static boolean[] repeat(final boolean element, final int n) {
final boolean[] a = new boolean[n];
N.fill(a, element);
return a;
}
public static char[] repeat(final char element, final int n) {
final char[] a = new char[n];
N.fill(a, element);
return a;
}
public static byte[] repeat(final byte element, final int n) {
final byte[] a = new byte[n];
N.fill(a, element);
return a;
}
public static short[] repeat(final short element, final int n) {
final short[] a = new short[n];
N.fill(a, element);
return a;
}
public static int[] repeat(final int element, final int n) {
final int[] a = new int[n];
N.fill(a, element);
return a;
}
public static long[] repeat(final long element, final int n) {
final long[] a = new long[n];
N.fill(a, element);
return a;
}
public static float[] repeat(final float element, final int n) {
final float[] a = new float[n];
N.fill(a, element);
return a;
}
public static double[] repeat(final double element, final int n) {
final double[] a = new double[n];
N.fill(a, element);
return a;
}
/**
*
* @param element
* @param n
* @return
* @throws NullPointerException if the specified {@code element} is null.
*/
public static T[] repeat(final T element, final int n) throws NullPointerException {
final T[] a = N.newArray(element.getClass(), n);
N.fill(a, element);
return a;
}
/**
*
* Converts an array of primitive booleans to objects.
*
*
*
* This method returns {@code null} for a {@code null} input array.
*
*
* @param a
* a {@code boolean} array
* @return a {@code Boolean} array, {@code null} if null array input
*/
@SafeVarargs
public static Boolean[] box(final boolean... a) {
if (a == null) {
return null;
}
return box(a, 0, a.length);
}
public static Boolean[] box(final boolean[] a, final int fromIndex, final int toIndex) {
if (a == null) {
return null;
} else if (toIndex - fromIndex == 0) {
return N.EMPTY_BOOLEAN_OBJECT_ARRAY;
}
final Boolean[] result = new Boolean[toIndex - fromIndex];
for (int i = 0, j = fromIndex; j < toIndex; i++, j++) {
result[i] = Boolean.valueOf(a[j]);
}
return result;
}
/**
*
* Converts an array of primitive chars to objects.
*
*
*
* This method returns {@code null} for a {@code null} input array.
*
*
* @param a
* a {@code char} array
* @return a {@code Character} array, {@code null} if null array input
*/
@SafeVarargs
public static Character[] box(final char... a) {
if (a == null) {
return null;
}
return box(a, 0, a.length);
}
public static Character[] box(final char[] a, final int fromIndex, final int toIndex) {
if (a == null) {
return null;
} else if (toIndex - fromIndex == 0) {
return N.EMPTY_CHARACTER_OBJECT_ARRAY;
}
final Character[] result = new Character[toIndex - fromIndex];
for (int i = 0, j = fromIndex; j < toIndex; i++, j++) {
result[i] = Character.valueOf(a[j]);
}
return result;
}
/**
*
* Converts an array of primitive bytes to objects.
*
*
*
* This method returns {@code null} for a {@code null} input array.
*
*
* @param a
* a {@code byte} array
* @return a {@code Byte} array, {@code null} if null array input
*/
@SafeVarargs
public static Byte[] box(final byte... a) {
if (a == null) {
return null;
}
return box(a, 0, a.length);
}
public static Byte[] box(final byte[] a, final int fromIndex, final int toIndex) {
if (a == null) {
return null;
} else if (toIndex - fromIndex == 0) {
return N.EMPTY_BYTE_OBJECT_ARRAY;
}
final Byte[] result = new Byte[toIndex - fromIndex];
for (int i = 0, j = fromIndex; j < toIndex; i++, j++) {
result[i] = Byte.valueOf(a[j]);
}
return result;
}
/**
*
* Converts an array of primitive shorts to objects.
*
*
*
* This method returns {@code null} for a {@code null} input array.
*
*
* @param a
* a {@code short} array
* @return a {@code Short} array, {@code null} if null array input
*/
@SafeVarargs
public static Short[] box(final short... a) {
if (a == null) {
return null;
}
return box(a, 0, a.length);
}
public static Short[] box(final short[] a, final int fromIndex, final int toIndex) {
if (a == null) {
return null;
} else if (toIndex - fromIndex == 0) {
return N.EMPTY_SHORT_OBJECT_ARRAY;
}
final Short[] result = new Short[toIndex - fromIndex];
for (int i = 0, j = fromIndex; j < toIndex; i++, j++) {
result[i] = Short.valueOf(a[j]);
}
return result;
}
/**
*
* Converts an array of primitive ints to objects.
*
*
*
* This method returns {@code null} for a {@code null} input array.
*
*
* @param a
* an {@code int} array
* @return an {@code Integer} array, {@code null} if null array input
*/
@SafeVarargs
public static Integer[] box(final int... a) {
if (a == null) {
return null;
}
return box(a, 0, a.length);
}
public static Integer[] box(final int[] a, final int fromIndex, final int toIndex) {
if (a == null) {
return null;
} else if (toIndex - fromIndex == 0) {
return N.EMPTY_INTEGER_OBJECT_ARRAY;
}
final Integer[] result = new Integer[toIndex - fromIndex];
for (int i = 0, j = fromIndex; j < toIndex; i++, j++) {
result[i] = Integer.valueOf(a[j]);
}
return result;
}
/**
*
* Converts an array of primitive longs to objects.
*
*
*
* This method returns {@code null} for a {@code null} input array.
*
*
* @param a
* a {@code long} array
* @return a {@code Long} array, {@code null} if null array input
*/
@SafeVarargs
public static Long[] box(final long... a) {
if (a == null) {
return null;
}
return box(a, 0, a.length);
}
public static Long[] box(final long[] a, final int fromIndex, final int toIndex) {
if (a == null) {
return null;
} else if (toIndex - fromIndex == 0) {
return N.EMPTY_LONG_OBJECT_ARRAY;
}
final Long[] result = new Long[toIndex - fromIndex];
for (int i = 0, j = fromIndex; j < toIndex; i++, j++) {
result[i] = Long.valueOf(a[j]);
}
return result;
}
/**
*
* Converts an array of primitive floats to objects.
*
*
*
* This method returns {@code null} for a {@code null} input array.
*
*
* @param a
* a {@code float} array
* @return a {@code Float} array, {@code null} if null array input
*/
@SafeVarargs
public static Float[] box(final float... a) {
if (a == null) {
return null;
}
return box(a, 0, a.length);
}
public static Float[] box(final float[] a, final int fromIndex, final int toIndex) {
if (a == null) {
return null;
} else if (toIndex - fromIndex == 0) {
return N.EMPTY_FLOAT_OBJECT_ARRAY;
}
final Float[] result = new Float[toIndex - fromIndex];
for (int i = 0, j = fromIndex; j < toIndex; i++, j++) {
result[i] = Float.valueOf(a[j]);
}
return result;
}
/**
*
* Converts an array of primitive doubles to objects.
*
*
*
* This method returns {@code null} for a {@code null} input array.
*
*
* @param a
* a {@code double} array
* @return a {@code Double} array, {@code null} if null array input
*/
@SafeVarargs
public static Double[] box(final double... a) {
if (a == null) {
return null;
}
return box(a, 0, a.length);
}
public static Double[] box(final double[] a, final int fromIndex, final int toIndex) {
if (a == null) {
return null;
} else if (toIndex - fromIndex == 0) {
return N.EMPTY_DOUBLE_OBJECT_ARRAY;
}
final Double[] result = new Double[toIndex - fromIndex];
for (int i = 0, j = fromIndex; j < toIndex; i++, j++) {
result[i] = Double.valueOf(a[j]);
}
return result;
}
static T box(final Object a) {
if (a == null) {
return null;
}
return box(a, 0, getLength(a));
}
static T box(final Object a, final int fromIndex, final int toIndex) {
if (a == null) {
return null;
}
final Class> cls = a.getClass();
final Integer enumInt = N.CLASS_TYPE_ENUM.get(cls);
if (enumInt == null) {
throw new IllegalArgumentException(ClassUtil.getCanonicalClassName(cls) + " is not a primitive array");
}
switch (enumInt) {
case 11:
return (T) box((boolean[]) a, fromIndex, toIndex);
case 12:
return (T) box((char[]) a, fromIndex, toIndex);
case 13:
return (T) box((byte[]) a, fromIndex, toIndex);
case 14:
return (T) box((short[]) a, fromIndex, toIndex);
case 15:
return (T) box((int[]) a, fromIndex, toIndex);
case 16:
return (T) box((long[]) a, fromIndex, toIndex);
case 17:
return (T) box((float[]) a, fromIndex, toIndex);
case 18:
return (T) box((double[]) a, fromIndex, toIndex);
default:
throw new IllegalArgumentException(ClassUtil.getCanonicalClassName(cls) + " is not a primitive array");
}
}
public static Boolean[][] box(boolean[][] a) {
if (a == null) {
return null;
}
final Boolean[][] result = new Boolean[a.length][];
for (int i = 0, len = a.length; i < len; i++) {
result[i] = box(a[i]);
}
return result;
}
public static Character[][] box(char[][] a) {
if (a == null) {
return null;
}
final Character[][] result = new Character[a.length][];
for (int i = 0, len = a.length; i < len; i++) {
result[i] = box(a[i]);
}
return result;
}
public static Byte[][] box(byte[][] a) {
if (a == null) {
return null;
}
final Byte[][] result = new Byte[a.length][];
for (int i = 0, len = a.length; i < len; i++) {
result[i] = box(a[i]);
}
return result;
}
public static Short[][] box(short[][] a) {
if (a == null) {
return null;
}
final Short[][] result = new Short[a.length][];
for (int i = 0, len = a.length; i < len; i++) {
result[i] = box(a[i]);
}
return result;
}
public static Integer[][] box(int[][] a) {
if (a == null) {
return null;
}
final Integer[][] result = new Integer[a.length][];
for (int i = 0, len = a.length; i < len; i++) {
result[i] = box(a[i]);
}
return result;
}
public static Long[][] box(long[][] a) {
if (a == null) {
return null;
}
final Long[][] result = new Long[a.length][];
for (int i = 0, len = a.length; i < len; i++) {
result[i] = box(a[i]);
}
return result;
}
public static Float[][] box(float[][] a) {
if (a == null) {
return null;
}
final Float[][] result = new Float[a.length][];
for (int i = 0, len = a.length; i < len; i++) {
result[i] = box(a[i]);
}
return result;
}
public static Double[][] box(double[][] a) {
if (a == null) {
return null;
}
final Double[][] result = new Double[a.length][];
for (int i = 0, len = a.length; i < len; i++) {
result[i] = box(a[i]);
}
return result;
}
// Boolean array converters
// ----------------------------------------------------------------------
/**
*
* Converts an array of object Booleans to primitives.
*
*
*
* This method returns {@code null} for a {@code null} input array.
*
*
* @param a
* a {@code Boolean} array, may be {@code null}
* @return a {@code boolean} array, {@code null} if null array input
*/
@SafeVarargs
public static boolean[] unbox(final Boolean... a) {
return unbox(a, false);
}
/**
*
* Converts an array of object Booleans to primitives handling {@code null}.
*
*
*
* This method returns {@code null} for a {@code null} input array.
*
*
* @param a
* a {@code Boolean} array, may be {@code null}
* @param valueForNull
* the value to insert if {@code null} found
* @return a {@code boolean} array, {@code null} if null array input
*/
public static boolean[] unbox(final Boolean[] a, final boolean valueForNull) {
if (a == null) {
return null;
}
return unbox(a, 0, a.length, valueForNull);
}
public static boolean[] unbox(final Boolean[] a, final int fromIndex, final int toIndex, final boolean valueForNull) {
if (a == null) {
return null;
} else if (toIndex - fromIndex == 0) {
return N.EMPTY_BOOLEAN_ARRAY;
}
final boolean[] result = new boolean[toIndex - fromIndex];
for (int i = 0, j = fromIndex; j < toIndex; i++, j++) {
result[i] = (a[j] == null ? valueForNull : a[j].booleanValue());
}
return result;
}
// Character array converters
// ----------------------------------------------------------------------
/**
*
* Converts an array of object Characters to primitives.
*
*
*
* This method returns {@code null} for a {@code null} input array.
*
*
* @param a
* a {@code Character} array, may be {@code null}
* @return a {@code char} array, {@code null} if null array input
*/
@SafeVarargs
public static char[] unbox(final Character... a) {
return unbox(a, (char) 0);
}
/**
*
* Converts an array of object Character to primitives handling {@code null}
* .
*
*
*
* This method returns {@code null} for a {@code null} input array.
*
*
* @param a
* a {@code Character} array, may be {@code null}
* @param valueForNull
* the value to insert if {@code null} found
* @return a {@code char} array, {@code null} if null array input
*/
public static char[] unbox(final Character[] a, final char valueForNull) {
if (a == null) {
return null;
}
return unbox(a, 0, a.length, valueForNull);
}
public static char[] unbox(final Character[] a, final int fromIndex, final int toIndex, final char valueForNull) {
if (a == null) {
return null;
} else if (toIndex - fromIndex == 0) {
return N.EMPTY_CHAR_ARRAY;
}
final char[] result = new char[toIndex - fromIndex];
for (int i = 0, j = fromIndex; j < toIndex; i++, j++) {
result[i] = (a[j] == null ? valueForNull : a[j].charValue());
}
return result;
}
// Byte array converters
// ----------------------------------------------------------------------
/**
*
* Converts an array of object Bytes to primitives.
*
*
*
* This method returns {@code null} for a {@code null} input array.
*
*
* @param a
* a {@code Byte} array, may be {@code null}
* @return a {@code byte} array, {@code null} if null array input
*/
@SafeVarargs
public static byte[] unbox(final Byte... a) {
return unbox(a, (byte) 0);
}
/**
*
* Converts an array of object Bytes to primitives handling {@code null}.
*
*
*
* This method returns {@code null} for a {@code null} input array.
*
*
* @param a
* a {@code Byte} array, may be {@code null}
* @param valueForNull
* the value to insert if {@code null} found
* @return a {@code byte} array, {@code null} if null array input
*/
public static byte[] unbox(final Byte[] a, final byte valueForNull) {
if (a == null) {
return null;
}
return unbox(a, 0, a.length, valueForNull);
}
public static byte[] unbox(final Byte[] a, final int fromIndex, final int toIndex, final byte valueForNull) {
if (a == null) {
return null;
} else if (toIndex - fromIndex == 0) {
return N.EMPTY_BYTE_ARRAY;
}
final byte[] result = new byte[toIndex - fromIndex];
for (int i = 0, j = fromIndex; j < toIndex; i++, j++) {
result[i] = (a[j] == null ? valueForNull : a[j].byteValue());
}
return result;
}
// Short array converters
// ----------------------------------------------------------------------
/**
*
* Converts an array of object Shorts to primitives.
*
*
*
* This method returns {@code null} for a {@code null} input array.
*
*
* @param a
* a {@code Short} array, may be {@code null}
* @return a {@code byte} array, {@code null} if null array input
*/
@SafeVarargs
public static short[] unbox(final Short... a) {
return unbox(a, (short) 0);
}
/**
*
* Converts an array of object Short to primitives handling {@code null}.
*
*
*
* This method returns {@code null} for a {@code null} input array.
*
*
* @param a
* a {@code Short} array, may be {@code null}
* @param valueForNull
* the value to insert if {@code null} found
* @return a {@code byte} array, {@code null} if null array input
*/
public static short[] unbox(final Short[] a, final short valueForNull) {
if (a == null) {
return null;
}
return unbox(a, 0, a.length, valueForNull);
}
public static short[] unbox(final Short[] a, final int fromIndex, final int toIndex, final short valueForNull) {
if (a == null) {
return null;
} else if (toIndex - fromIndex == 0) {
return N.EMPTY_SHORT_ARRAY;
}
final short[] result = new short[toIndex - fromIndex];
for (int i = 0, j = fromIndex; j < toIndex; i++, j++) {
result[i] = (a[j] == null ? valueForNull : a[j].shortValue());
}
return result;
}
// Int array converters
// ----------------------------------------------------------------------
/**
*
* Converts an array of object Integers to primitives.
*
*
*
* This method returns {@code null} for a {@code null} input array.
*
*
* @param a
* a {@code Integer} array, may be {@code null}
* @return an {@code int} array, {@code null} if null array input
*/
@SafeVarargs
public static int[] unbox(final Integer... a) {
return unbox(a, 0);
}
/**
*
* Converts an array of object Integer to primitives handling {@code null}.
*
*
*
* This method returns {@code null} for a {@code null} input array.
*
*
* @param a
* a {@code Integer} array, may be {@code null}
* @param valueForNull
* the value to insert if {@code null} found
* @return an {@code int} array, {@code null} if null array input
*/
public static int[] unbox(final Integer[] a, final int valueForNull) {
if (a == null) {
return null;
}
return unbox(a, 0, a.length, valueForNull);
}
public static int[] unbox(final Integer[] a, final int fromIndex, final int toIndex, final int valueForNull) {
if (a == null) {
return null;
} else if (toIndex - fromIndex == 0) {
return N.EMPTY_INT_ARRAY;
}
final int[] result = new int[toIndex - fromIndex];
for (int i = 0, j = fromIndex; j < toIndex; i++, j++) {
result[i] = (a[j] == null ? valueForNull : a[j].intValue());
}
return result;
}
// Long array converters
// ----------------------------------------------------------------------
/**
*
* Converts an array of object Longs to primitives.
*
*
*
* This method returns {@code null} for a {@code null} input array.
*
*
* @param a
* a {@code Long} array, may be {@code null}
* @return a {@code long} array, {@code null} if null array input
*/
@SafeVarargs
public static long[] unbox(final Long... a) {
return unbox(a, 0L);
}
/**
*
* Converts an array of object Long to primitives handling {@code null}.
*
*
*
* This method returns {@code null} for a {@code null} input array.
*
*
* @param a
* a {@code Long} array, may be {@code null}
* @param valueForNull
* the value to insert if {@code null} found
* @return a {@code long} array, {@code null} if null array input
*/
public static long[] unbox(final Long[] a, final long valueForNull) {
if (a == null) {
return null;
}
return unbox(a, 0, a.length, valueForNull);
}
public static long[] unbox(final Long[] a, final int fromIndex, final int toIndex, final long valueForNull) {
if (a == null) {
return null;
} else if (toIndex - fromIndex == 0) {
return N.EMPTY_LONG_ARRAY;
}
final long[] result = new long[toIndex - fromIndex];
for (int i = 0, j = fromIndex; j < toIndex; i++, j++) {
result[i] = (a[j] == null ? valueForNull : a[j].longValue());
}
return result;
}
// Float array converters
// ----------------------------------------------------------------------
/**
*
* Converts an array of object Floats to primitives.
*
*
*
* This method returns {@code null} for a {@code null} input array.
*
*
* @param a
* a {@code Float} array, may be {@code null}
* @return a {@code float} array, {@code null} if null array input
*/
@SafeVarargs
public static float[] unbox(final Float... a) {
return unbox(a, 0f);
}
/**
*
* Converts an array of object Floats to primitives handling {@code null}.
*
*
*
* This method returns {@code null} for a {@code null} input array.
*
*
* @param a
* a {@code Float} array, may be {@code null}
* @param valueForNull
* the value to insert if {@code null} found
* @return a {@code float} array, {@code null} if null array input
*/
public static float[] unbox(final Float[] a, final float valueForNull) {
if (a == null) {
return null;
}
return unbox(a, 0, a.length, valueForNull);
}
public static float[] unbox(final Float[] a, final int fromIndex, final int toIndex, final float valueForNull) {
if (a == null) {
return null;
} else if (toIndex - fromIndex == 0) {
return N.EMPTY_FLOAT_ARRAY;
}
final float[] result = new float[toIndex - fromIndex];
for (int i = 0, j = fromIndex; j < toIndex; i++, j++) {
result[i] = (a[j] == null ? valueForNull : a[j].floatValue());
}
return result;
}
// Double array converters
// ----------------------------------------------------------------------
/**
*
* Converts an array of object Doubles to primitives.
*
*
*
* This method returns {@code null} for a {@code null} input array.
*
*
* @param a
* a {@code Double} array, may be {@code null}
* @return a {@code double} array, {@code null} if null array input
*/
@SafeVarargs
public static double[] unbox(final Double... a) {
return unbox(a, 0d);
}
/**
*
* Converts an array of object Doubles to primitives handling {@code null}.
*
*
*
* This method returns {@code null} for a {@code null} input array.
*
*
* @param a
* a {@code Double} array, may be {@code null}
* @param valueForNull
* the value to insert if {@code null} found
* @return a {@code double} array, {@code null} if null array input
*/
public static double[] unbox(final Double[] a, final double valueForNull) {
if (a == null) {
return null;
}
return unbox(a, 0, a.length, valueForNull);
}
public static double[] unbox(final Double[] a, final int fromIndex, final int toIndex, final double valueForNull) {
if (a == null) {
return null;
} else if (toIndex - fromIndex == 0) {
return N.EMPTY_DOUBLE_ARRAY;
}
final double[] result = new double[toIndex - fromIndex];
for (int i = 0, j = fromIndex; j < toIndex; i++, j++) {
result[i] = (a[j] == null ? valueForNull : a[j].doubleValue());
}
return result;
}
public static boolean[][] unbox(Boolean[][] a) {
return unbox(a, false);
}
public static boolean[][] unbox(Boolean[][] a, boolean valueForNull) {
if (a == null) {
return null;
}
final boolean[][] result = new boolean[a.length][];
for (int i = 0, len = a.length; i < len; i++) {
result[i] = unbox(a[i], valueForNull);
}
return result;
}
public static char[][] unbox(Character[][] a) {
return unbox(a, (char) 0);
}
public static char[][] unbox(Character[][] a, char valueForNull) {
if (a == null) {
return null;
}
final char[][] result = new char[a.length][];
for (int i = 0, len = a.length; i < len; i++) {
result[i] = unbox(a[i], valueForNull);
}
return result;
}
public static byte[][] unbox(Byte[][] a) {
return unbox(a, (byte) 0);
}
public static byte[][] unbox(Byte[][] a, byte valueForNull) {
if (a == null) {
return null;
}
final byte[][] result = new byte[a.length][];
for (int i = 0, len = a.length; i < len; i++) {
result[i] = unbox(a[i], valueForNull);
}
return result;
}
public static short[][] unbox(Short[][] a) {
return unbox(a, (short) 0);
}
public static short[][] unbox(Short[][] a, short valueForNull) {
if (a == null) {
return null;
}
final short[][] result = new short[a.length][];
for (int i = 0, len = a.length; i < len; i++) {
result[i] = unbox(a[i], valueForNull);
}
return result;
}
public static int[][] unbox(Integer[][] a) {
return unbox(a, 0);
}
public static int[][] unbox(Integer[][] a, int valueForNull) {
if (a == null) {
return null;
}
final int[][] result = new int[a.length][];
for (int i = 0, len = a.length; i < len; i++) {
result[i] = unbox(a[i], valueForNull);
}
return result;
}
public static long[][] unbox(Long[][] a) {
return unbox(a, 0);
}
public static long[][] unbox(Long[][] a, long valueForNull) {
if (a == null) {
return null;
}
final long[][] result = new long[a.length][];
for (int i = 0, len = a.length; i < len; i++) {
result[i] = unbox(a[i], valueForNull);
}
return result;
}
public static float[][] unbox(Float[][] a) {
return unbox(a, 0);
}
public static float[][] unbox(Float[][] a, float valueForNull) {
if (a == null) {
return null;
}
final float[][] result = new float[a.length][];
for (int i = 0, len = a.length; i < len; i++) {
result[i] = unbox(a[i], valueForNull);
}
return result;
}
public static double[][] unbox(Double[][] a) {
return unbox(a, 0);
}
public static double[][] unbox(Double[][] a, double valueForNull) {
if (a == null) {
return null;
}
final double[][] result = new double[a.length][];
for (int i = 0, len = a.length; i < len; i++) {
result[i] = unbox(a[i], valueForNull);
}
return result;
}
static T unbox(final Object a) {
if (a == null) {
return null;
}
return unbox(a, null);
}
static T unbox(final Object a, final Object valueForNull) {
if (a == null) {
return null;
}
return unbox(a, 0, getLength(a), valueForNull);
}
static T unbox(final Object a, final int fromIndex, final int toIndex, final Object valueForNull) {
if (a == null) {
return null;
}
final Class> cls = Primitives.unwrap(a.getClass());
final Object defaultValue = valueForNull == null ? N.defaultValueOf(cls.getComponentType()) : valueForNull;
final Integer enumInt = N.CLASS_TYPE_ENUM.get(cls);
if (enumInt == null) {
throw new IllegalArgumentException(ClassUtil.getCanonicalClassName(a.getClass()) + " is not a wrapper of primitive array");
}
switch (enumInt) {
case 11:
return (T) unbox((Boolean[]) a, fromIndex, toIndex, ((Boolean) defaultValue).booleanValue());
case 12:
return (T) unbox((Character[]) a, fromIndex, toIndex, ((Character) defaultValue).charValue());
case 13:
return (T) unbox((Byte[]) a, fromIndex, toIndex, ((Number) defaultValue).byteValue());
case 14:
return (T) unbox((Short[]) a, fromIndex, toIndex, ((Number) defaultValue).shortValue());
case 15:
return (T) unbox((Integer[]) a, fromIndex, toIndex, ((Number) defaultValue).intValue());
case 16:
return (T) unbox((Long[]) a, fromIndex, toIndex, ((Number) defaultValue).longValue());
case 17:
return (T) unbox((Float[]) a, fromIndex, toIndex, ((Number) defaultValue).floatValue());
case 18:
return (T) unbox((Double[]) a, fromIndex, toIndex, ((Number) defaultValue).doubleValue());
default:
throw new IllegalArgumentException(ClassUtil.getCanonicalClassName(a.getClass()) + " is not a wrapper of primitive array");
}
}
static void sort(final boolean[] a) {
if (N.isNullOrEmpty(a)) {
return;
}
int numOfFalse = 0;
for (int i = 0, len = a.length; i < len; i++) {
if (a[i] == false) {
numOfFalse++;
}
}
N.fill(a, 0, numOfFalse, false);
N.fill(a, numOfFalse, a.length, true);
}
static void reverseSort(final boolean[] a) {
if (N.isNullOrEmpty(a)) {
return;
}
int numOfTrue = 0;
for (int i = 0, len = a.length; i < len; i++) {
if (a[i]) {
numOfTrue++;
}
}
N.fill(a, 0, numOfTrue, true);
N.fill(a, numOfTrue, a.length, false);
}
static void sort(final char[] a) {
if (N.isNullOrEmpty(a)) {
return;
}
Arrays.sort(a);
}
static void sort(final char[] a, final int fromIndex, final int toIndex) {
N.checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length);
if (N.isNullOrEmpty(a) || fromIndex == toIndex) {
return;
}
Arrays.sort(a, fromIndex, toIndex);
}
static void sort(final byte[] a) {
if (N.isNullOrEmpty(a)) {
return;
}
Arrays.sort(a);
}
static void sort(final byte[] a, final int fromIndex, final int toIndex) {
N.checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length);
if (N.isNullOrEmpty(a) || fromIndex == toIndex) {
return;
}
Arrays.sort(a, fromIndex, toIndex);
}
static void sort(final short[] a) {
if (N.isNullOrEmpty(a)) {
return;
}
Arrays.sort(a);
}
static void sort(final short[] a, final int fromIndex, final int toIndex) {
N.checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length);
if (N.isNullOrEmpty(a) || fromIndex == toIndex) {
return;
}
Arrays.sort(a, fromIndex, toIndex);
}
static void sort(final int[] a) {
if (N.isNullOrEmpty(a)) {
return;
}
Arrays.sort(a);
}
static void sort(final int[] a, final int fromIndex, final int toIndex) {
N.checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length);
if (N.isNullOrEmpty(a) || fromIndex == toIndex) {
return;
}
Arrays.sort(a, fromIndex, toIndex);
}
static void sort(final long[] a) {
if (N.isNullOrEmpty(a)) {
return;
}
Arrays.sort(a);
}
static void sort(final long[] a, final int fromIndex, final int toIndex) {
N.checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length);
if (N.isNullOrEmpty(a) || fromIndex == toIndex) {
return;
}
Arrays.sort(a, fromIndex, toIndex);
}
static void sort(final float[] a) {
if (N.isNullOrEmpty(a)) {
return;
}
Arrays.sort(a);
}
static void sort(final float[] a, final int fromIndex, final int toIndex) {
N.checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length);
if (N.isNullOrEmpty(a) || fromIndex == toIndex) {
return;
}
Arrays.sort(a, fromIndex, toIndex);
}
static void sort(final double[] a) {
if (N.isNullOrEmpty(a)) {
return;
}
Arrays.sort(a);
}
static void sort(final double[] a, final int fromIndex, final int toIndex) {
N.checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length);
if (N.isNullOrEmpty(a) || fromIndex == toIndex) {
return;
}
Arrays.sort(a, fromIndex, toIndex);
}
static void sort(final Object[] a) {
if (N.isNullOrEmpty(a)) {
return;
}
sort(a, 0, a.length);
}
static void sort(final Object[] a, final int fromIndex, final int toIndex) {
sort(a, fromIndex, toIndex, Comparators.NATURAL_ORDER);
}
static void sort(final T[] a, final Comparator super T> cmp) {
if (N.isNullOrEmpty(a)) {
return;
}
sort(a, 0, a.length, cmp);
}
static void sort(final T[] a, final int fromIndex, final int toIndex, final Comparator super T> cmp) {
N.checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length);
if (N.isNullOrEmpty(a) || fromIndex == toIndex) {
return;
}
Arrays.sort(a, fromIndex, toIndex, cmp);
}
static > void sort(final List extends T> c) {
if (N.isNullOrEmpty(c)) {
return;
}
sort(c, 0, c.size());
}
static > void sort(final List extends T> c, final int fromIndex, final int toIndex) {
sort(c, fromIndex, toIndex, Comparators.NATURAL_ORDER);
}
static void sort(final List extends T> list, final Comparator super T> cmp) {
if (N.isNullOrEmpty(list)) {
return;
}
sort(list, 0, list.size(), cmp);
}
@SuppressWarnings("rawtypes")
static void sort(final List extends T> c, final int fromIndex, final int toIndex, final Comparator super T> cmp) {
if ((N.isNullOrEmpty(c) && fromIndex == 0 && toIndex == 0) || fromIndex == toIndex) {
return;
}
if (N.isListElementDataFieldGettable && N.listElementDataField != null && c instanceof ArrayList) {
T[] array = null;
try {
array = (T[]) N.listElementDataField.get(c);
} catch (Exception e) {
// ignore;
N.isListElementDataFieldGettable = false;
}
if (array != null) {
sort(array, fromIndex, toIndex, cmp);
return;
}
}
final T[] array = (T[]) c.toArray();
Arrays.sort(array, fromIndex, toIndex, cmp);
final ListIterator i = c.listIterator();
for (int j = 0; j < array.length; j++) {
i.next();
i.set(array[j]);
}
}
// ============================= Java 8 and above
// static void parallelSort(final char[] a) {
// if (N.isNullOrEmpty(a)) {
// return;
// }
//
// Arrays.parallelSort(a);
// }
//
// static void parallelSort(final char[] a, final int fromIndex, final int toIndex) {
// if (N.isNullOrEmpty(a)) {
// return;
// }
//
// Arrays.parallelSort(a, fromIndex, toIndex);
// }
//
// static void parallelSort(final byte[] a) {
// if (N.isNullOrEmpty(a)) {
// return;
// }
//
// Arrays.parallelSort(a);
// }
//
// static void parallelSort(final byte[] a, final int fromIndex, final int toIndex) {
// if (N.isNullOrEmpty(a)) {
// return;
// }
//
// Arrays.parallelSort(a, fromIndex, toIndex);
// }
//
// static void parallelSort(final short[] a) {
// if (N.isNullOrEmpty(a)) {
// return;
// }
//
// Arrays.parallelSort(a);
// }
//
// static void parallelSort(final short[] a, final int fromIndex, final int toIndex) {
// if (N.isNullOrEmpty(a)) {
// return;
// }
//
// Arrays.parallelSort(a, fromIndex, toIndex);
// }
//
// static void parallelSort(final int[] a) {
// if (N.isNullOrEmpty(a)) {
// return;
// }
//
// Arrays.parallelSort(a);
// }
//
// static void parallelSort(final int[] a, final int fromIndex, final int toIndex) {
// if (N.isNullOrEmpty(a)) {
// return;
// }
//
// Arrays.parallelSort(a, fromIndex, toIndex);
// }
//
// static void parallelSort(final long[] a) {
// if (N.isNullOrEmpty(a)) {
// return;
// }
//
// Arrays.parallelSort(a);
// }
//
// static void parallelSort(final long[] a, final int fromIndex, final int toIndex) {
// if (N.isNullOrEmpty(a)) {
// return;
// }
//
// Arrays.parallelSort(a, fromIndex, toIndex);
// }
//
// static void parallelSort(final float[] a) {
// if (N.isNullOrEmpty(a)) {
// return;
// }
//
// Arrays.parallelSort(a);
// }
//
// static void parallelSort(final float[] a, final int fromIndex, final int toIndex) {
// if (N.isNullOrEmpty(a)) {
// return;
// }
//
// Arrays.parallelSort(a, fromIndex, toIndex);
// }
//
// static void parallelSort(final double[] a) {
// if (N.isNullOrEmpty(a)) {
// return;
// }
//
// Arrays.parallelSort(a);
// }
//
// static void parallelSort(final double[] a, final int fromIndex, final int toIndex) {
// if (N.isNullOrEmpty(a)) {
// return;
// }
//
// Arrays.parallelSort(a, fromIndex, toIndex);
// }
//
// static void parallelSort(Object[] a) {
// if (N.isNullOrEmpty(a)) {
// return;
// }
//
// Arrays.parallelSort(a, N.OBJECT_COMPARATOR);
// }
//
// static void parallelSort(Object[] a, int fromIndex, int toIndex) {
// if (N.isNullOrEmpty(a)) {
// return;
// }
//
// Arrays.parallelSort(a, fromIndex, toIndex, N.OBJECT_COMPARATOR);
// }
//
// static void parallelSort(final T[] a, final Comparator super T> cmp) {
// if (N.isNullOrEmpty(a)) {
// return;
// }
//
// Arrays.parallelSort(a, cmp);
// }
//
// static void parallelSort(final T[] a, final int fromIndex, final int toIndex, final Comparator super T> cmp) {
// if (N.isNullOrEmpty(a)) {
// return;
// }
//
// Arrays.parallelSort(a, fromIndex, toIndex, cmp);
// }
static void parallelSort(final char[] array) {
if (N.isNullOrEmpty(array)) {
return;
}
parallelSort(array, 0, array.length);
}
static void parallelSort(final char[] a, final int fromIndex, final int toIndex) {
N.checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length);
if (N.isNullOrEmpty(a) || fromIndex == toIndex) {
return;
}
final int len = toIndex - fromIndex;
if (len < MIN_ARRAY_SORT_GRAN || CPU_CORES == 1) {
sort(a, fromIndex, toIndex);
return;
}
final Queue> subArrayIndexQueue = new LinkedList<>();
final AtomicInteger activeThreadNum = new AtomicInteger();
final Holder errorHolder = new Holder<>();
final int lenOfSubArray = len % CPU_CORES == 0 ? len / CPU_CORES : (len / CPU_CORES) + 1;
for (int i = 0; i < CPU_CORES; i++) {
final int start = fromIndex + i * lenOfSubArray;
final int end = toIndex - start < lenOfSubArray ? toIndex : start + lenOfSubArray;
subArrayIndexQueue.add(Pair.of(start, end));
activeThreadNum.incrementAndGet();
parallelSortExecutor.execute(new Runnable() {
@Override
public void run() {
try {
if (errorHolder.value() != null) {
return;
}
Arrays.sort(a, start, end);
} catch (Exception e) {
setError(errorHolder, e);
} finally {
activeThreadNum.decrementAndGet();
}
}
});
}
while (activeThreadNum.get() > 0) {
N.sleep(1);
}
if (errorHolder.value() != null) {
throw N.toRuntimeException(errorHolder.value());
}
while (subArrayIndexQueue.size() > 1 && errorHolder.value() == null) {
for (int i = 0, size = subArrayIndexQueue.size(); i < size;) {
final Pair pairA = subArrayIndexQueue.poll();
if (++i == size) {
subArrayIndexQueue.add(pairA);
} else {
i++;
final Pair pairB = subArrayIndexQueue.poll();
subArrayIndexQueue.offer(Pair.of(pairA.left, pairB.right));
activeThreadNum.incrementAndGet();
parallelSortExecutor.execute(new Runnable() {
@Override
public void run() {
try {
if (errorHolder.value() != null) {
return;
}
merge(N.copyOfRange(a, pairA.left, pairA.right), 0, pairA.right - pairA.left, a, pairB.left, pairB.right, pairA.left);
} catch (Exception e) {
setError(errorHolder, e);
} finally {
activeThreadNum.decrementAndGet();
}
}
});
}
}
while (activeThreadNum.get() > 0) {
N.sleep(1);
}
if (errorHolder.value() != null) {
throw N.toRuntimeException(errorHolder.value());
}
}
if (errorHolder.value() != null) {
throw N.toRuntimeException(errorHolder.value());
}
}
static void merge(final char[] a, int fromIndexA, int toIndexA, final char[] b, int fromIndexB, int toIndexB, int fromIndex) {
while (fromIndexA < toIndexA && fromIndexB < toIndexB) {
if (a[fromIndexA] <= b[fromIndexB]) {
b[fromIndex++] = a[fromIndexA++];
} else {
b[fromIndex++] = b[fromIndexB++];
}
}
if (fromIndexA < toIndexA) {
N.copy(a, fromIndexA, b, fromIndex, toIndexA - fromIndexA);
fromIndex += toIndexA - fromIndexA;
}
}
static void parallelSort(final byte[] array) {
if (N.isNullOrEmpty(array)) {
return;
}
parallelSort(array, 0, array.length);
}
static void parallelSort(final byte[] a, final int fromIndex, final int toIndex) {
N.checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length);
if (N.isNullOrEmpty(a) || fromIndex == toIndex) {
return;
}
final int len = toIndex - fromIndex;
if (len < MIN_ARRAY_SORT_GRAN || CPU_CORES == 1) {
sort(a, fromIndex, toIndex);
return;
}
final Queue> subArrayIndexQueue = new LinkedList<>();
final AtomicInteger activeThreadNum = new AtomicInteger();
final Holder errorHolder = new Holder<>();
final int lenOfSubArray = len % CPU_CORES == 0 ? len / CPU_CORES : (len / CPU_CORES) + 1;
for (int i = 0; i < CPU_CORES; i++) {
final int start = fromIndex + i * lenOfSubArray;
final int end = toIndex - start < lenOfSubArray ? toIndex : start + lenOfSubArray;
subArrayIndexQueue.add(Pair.of(start, end));
activeThreadNum.incrementAndGet();
parallelSortExecutor.execute(new Runnable() {
@Override
public void run() {
try {
if (errorHolder.value() != null) {
return;
}
Arrays.sort(a, start, end);
} catch (Exception e) {
setError(errorHolder, e);
} finally {
activeThreadNum.decrementAndGet();
}
}
});
}
while (activeThreadNum.get() > 0) {
N.sleep(1);
}
if (errorHolder.value() != null) {
throw N.toRuntimeException(errorHolder.value());
}
while (subArrayIndexQueue.size() > 1 && errorHolder.value() == null) {
for (int i = 0, size = subArrayIndexQueue.size(); i < size;) {
final Pair pairA = subArrayIndexQueue.poll();
if (++i == size) {
subArrayIndexQueue.add(pairA);
} else {
i++;
final Pair pairB = subArrayIndexQueue.poll();
subArrayIndexQueue.offer(Pair.of(pairA.left, pairB.right));
activeThreadNum.incrementAndGet();
parallelSortExecutor.execute(new Runnable() {
@Override
public void run() {
try {
if (errorHolder.value() != null) {
return;
}
merge(N.copyOfRange(a, pairA.left, pairA.right), 0, pairA.right - pairA.left, a, pairB.left, pairB.right, pairA.left);
} catch (Exception e) {
setError(errorHolder, e);
} finally {
activeThreadNum.decrementAndGet();
}
}
});
}
}
while (activeThreadNum.get() > 0) {
N.sleep(1);
}
if (errorHolder.value() != null) {
throw N.toRuntimeException(errorHolder.value());
}
}
if (errorHolder.value() != null) {
throw N.toRuntimeException(errorHolder.value());
}
}
static void merge(final byte[] a, int fromIndexA, int toIndexA, final byte[] b, int fromIndexB, int toIndexB, int fromIndex) {
while (fromIndexA < toIndexA && fromIndexB < toIndexB) {
if (a[fromIndexA] <= b[fromIndexB]) {
b[fromIndex++] = a[fromIndexA++];
} else {
b[fromIndex++] = b[fromIndexB++];
}
}
if (fromIndexA < toIndexA) {
N.copy(a, fromIndexA, b, fromIndex, toIndexA - fromIndexA);
fromIndex += toIndexA - fromIndexA;
}
}
static void parallelSort(final short[] array) {
if (N.isNullOrEmpty(array)) {
return;
}
parallelSort(array, 0, array.length);
}
static void parallelSort(final short[] a, final int fromIndex, final int toIndex) {
N.checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length);
if (N.isNullOrEmpty(a) || fromIndex == toIndex) {
return;
}
final int len = toIndex - fromIndex;
if (len < MIN_ARRAY_SORT_GRAN || CPU_CORES == 1) {
sort(a, fromIndex, toIndex);
return;
}
final Queue> subArrayIndexQueue = new LinkedList<>();
final AtomicInteger activeThreadNum = new AtomicInteger();
final Holder errorHolder = new Holder<>();
final int lenOfSubArray = len % CPU_CORES == 0 ? len / CPU_CORES : (len / CPU_CORES) + 1;
for (int i = 0; i < CPU_CORES; i++) {
final int start = fromIndex + i * lenOfSubArray;
final int end = toIndex - start < lenOfSubArray ? toIndex : start + lenOfSubArray;
subArrayIndexQueue.add(Pair.of(start, end));
activeThreadNum.incrementAndGet();
parallelSortExecutor.execute(new Runnable() {
@Override
public void run() {
try {
if (errorHolder.value() != null) {
return;
}
Arrays.sort(a, start, end);
} catch (Exception e) {
setError(errorHolder, e);
} finally {
activeThreadNum.decrementAndGet();
}
}
});
}
while (activeThreadNum.get() > 0) {
N.sleep(1);
}
if (errorHolder.value() != null) {
throw N.toRuntimeException(errorHolder.value());
}
while (subArrayIndexQueue.size() > 1 && errorHolder.value() == null) {
for (int i = 0, size = subArrayIndexQueue.size(); i < size;) {
final Pair pairA = subArrayIndexQueue.poll();
if (++i == size) {
subArrayIndexQueue.add(pairA);
} else {
i++;
final Pair pairB = subArrayIndexQueue.poll();
subArrayIndexQueue.offer(Pair.of(pairA.left, pairB.right));
activeThreadNum.incrementAndGet();
parallelSortExecutor.execute(new Runnable() {
@Override
public void run() {
try {
if (errorHolder.value() != null) {
return;
}
merge(N.copyOfRange(a, pairA.left, pairA.right), 0, pairA.right - pairA.left, a, pairB.left, pairB.right, pairA.left);
} catch (Exception e) {
setError(errorHolder, e);
} finally {
activeThreadNum.decrementAndGet();
}
}
});
}
}
while (activeThreadNum.get() > 0) {
N.sleep(1);
}
if (errorHolder.value() != null) {
throw N.toRuntimeException(errorHolder.value());
}
}
if (errorHolder.value() != null) {
throw N.toRuntimeException(errorHolder.value());
}
}
static void merge(final short[] a, int fromIndexA, int toIndexA, final short[] b, int fromIndexB, int toIndexB, int fromIndex) {
while (fromIndexA < toIndexA && fromIndexB < toIndexB) {
if (a[fromIndexA] <= b[fromIndexB]) {
b[fromIndex++] = a[fromIndexA++];
} else {
b[fromIndex++] = b[fromIndexB++];
}
}
if (fromIndexA < toIndexA) {
N.copy(a, fromIndexA, b, fromIndex, toIndexA - fromIndexA);
fromIndex += toIndexA - fromIndexA;
}
}
static void parallelSort(final int[] array) {
if (N.isNullOrEmpty(array)) {
return;
}
parallelSort(array, 0, array.length);
}
static void parallelSort(final int[] a, final int fromIndex, final int toIndex) {
N.checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length);
if (N.isNullOrEmpty(a) || fromIndex == toIndex) {
return;
}
final int len = toIndex - fromIndex;
if (len < MIN_ARRAY_SORT_GRAN || CPU_CORES == 1) {
sort(a, fromIndex, toIndex);
return;
}
final Queue> subArrayIndexQueue = new LinkedList<>();
final AtomicInteger activeThreadNum = new AtomicInteger();
final Holder errorHolder = new Holder<>();
final int lenOfSubArray = len % CPU_CORES == 0 ? len / CPU_CORES : (len / CPU_CORES) + 1;
for (int i = 0; i < CPU_CORES; i++) {
final int start = fromIndex + i * lenOfSubArray;
final int end = toIndex - start < lenOfSubArray ? toIndex : start + lenOfSubArray;
subArrayIndexQueue.add(Pair.of(start, end));
activeThreadNum.incrementAndGet();
parallelSortExecutor.execute(new Runnable() {
@Override
public void run() {
try {
if (errorHolder.value() != null) {
return;
}
Arrays.sort(a, start, end);
} catch (Exception e) {
setError(errorHolder, e);
} finally {
activeThreadNum.decrementAndGet();
}
}
});
}
while (activeThreadNum.get() > 0) {
N.sleep(1);
}
if (errorHolder.value() != null) {
throw N.toRuntimeException(errorHolder.value());
}
while (subArrayIndexQueue.size() > 1 && errorHolder.value() == null) {
for (int i = 0, size = subArrayIndexQueue.size(); i < size;) {
final Pair pairA = subArrayIndexQueue.poll();
if (++i == size) {
subArrayIndexQueue.add(pairA);
} else {
i++;
final Pair pairB = subArrayIndexQueue.poll();
subArrayIndexQueue.offer(Pair.of(pairA.left, pairB.right));
activeThreadNum.incrementAndGet();
parallelSortExecutor.execute(new Runnable() {
@Override
public void run() {
try {
if (errorHolder.value() != null) {
return;
}
merge(N.copyOfRange(a, pairA.left, pairA.right), 0, pairA.right - pairA.left, a, pairB.left, pairB.right, pairA.left);
} catch (Exception e) {
setError(errorHolder, e);
} finally {
activeThreadNum.decrementAndGet();
}
}
});
}
}
while (activeThreadNum.get() > 0) {
N.sleep(1);
}
if (errorHolder.value() != null) {
throw N.toRuntimeException(errorHolder.value());
}
}
if (errorHolder.value() != null) {
throw N.toRuntimeException(errorHolder.value());
}
}
static void merge(final int[] a, int fromIndexA, int toIndexA, final int[] b, int fromIndexB, int toIndexB, int fromIndex) {
while (fromIndexA < toIndexA && fromIndexB < toIndexB) {
if (a[fromIndexA] <= b[fromIndexB]) {
b[fromIndex++] = a[fromIndexA++];
} else {
b[fromIndex++] = b[fromIndexB++];
}
}
if (fromIndexA < toIndexA) {
N.copy(a, fromIndexA, b, fromIndex, toIndexA - fromIndexA);
fromIndex += toIndexA - fromIndexA;
}
}
static void parallelSort(final long[] array) {
if (N.isNullOrEmpty(array)) {
return;
}
parallelSort(array, 0, array.length);
}
static void parallelSort(final long[] a, final int fromIndex, final int toIndex) {
N.checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length);
if (N.isNullOrEmpty(a) || fromIndex == toIndex) {
return;
}
final int len = toIndex - fromIndex;
if (len < MIN_ARRAY_SORT_GRAN || CPU_CORES == 1) {
sort(a, fromIndex, toIndex);
return;
}
final Queue> subArrayIndexQueue = new LinkedList<>();
final AtomicInteger activeThreadNum = new AtomicInteger();
final Holder errorHolder = new Holder<>();
final int lenOfSubArray = len % CPU_CORES == 0 ? len / CPU_CORES : (len / CPU_CORES) + 1;
for (int i = 0; i < CPU_CORES; i++) {
final int start = fromIndex + i * lenOfSubArray;
final int end = toIndex - start < lenOfSubArray ? toIndex : start + lenOfSubArray;
subArrayIndexQueue.add(Pair.of(start, end));
activeThreadNum.incrementAndGet();
parallelSortExecutor.execute(new Runnable() {
@Override
public void run() {
try {
if (errorHolder.value() != null) {
return;
}
Arrays.sort(a, start, end);
} catch (Exception e) {
setError(errorHolder, e);
} finally {
activeThreadNum.decrementAndGet();
}
}
});
}
while (activeThreadNum.get() > 0) {
N.sleep(1);
}
if (errorHolder.value() != null) {
throw N.toRuntimeException(errorHolder.value());
}
while (subArrayIndexQueue.size() > 1 && errorHolder.value() == null) {
for (int i = 0, size = subArrayIndexQueue.size(); i < size;) {
final Pair pairA = subArrayIndexQueue.poll();
if (++i == size) {
subArrayIndexQueue.add(pairA);
} else {
i++;
final Pair pairB = subArrayIndexQueue.poll();
subArrayIndexQueue.offer(Pair.of(pairA.left, pairB.right));
activeThreadNum.incrementAndGet();
parallelSortExecutor.execute(new Runnable() {
@Override
public void run() {
try {
if (errorHolder.value() != null) {
return;
}
merge(N.copyOfRange(a, pairA.left, pairA.right), 0, pairA.right - pairA.left, a, pairB.left, pairB.right, pairA.left);
} catch (Exception e) {
setError(errorHolder, e);
} finally {
activeThreadNum.decrementAndGet();
}
}
});
}
}
while (activeThreadNum.get() > 0) {
N.sleep(1);
}
if (errorHolder.value() != null) {
throw N.toRuntimeException(errorHolder.value());
}
}
if (errorHolder.value() != null) {
throw N.toRuntimeException(errorHolder.value());
}
}
static void merge(final long[] a, int fromIndexA, int toIndexA, final long[] b, int fromIndexB, int toIndexB, int fromIndex) {
while (fromIndexA < toIndexA && fromIndexB < toIndexB) {
if (a[fromIndexA] <= b[fromIndexB]) {
b[fromIndex++] = a[fromIndexA++];
} else {
b[fromIndex++] = b[fromIndexB++];
}
}
if (fromIndexA < toIndexA) {
N.copy(a, fromIndexA, b, fromIndex, toIndexA - fromIndexA);
fromIndex += toIndexA - fromIndexA;
}
}
static void parallelSort(final float[] array) {
if (N.isNullOrEmpty(array)) {
return;
}
parallelSort(array, 0, array.length);
}
static void parallelSort(final float[] a, final int fromIndex, final int toIndex) {
N.checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length);
if (N.isNullOrEmpty(a) || fromIndex == toIndex) {
return;
}
final int len = toIndex - fromIndex;
if (len < MIN_ARRAY_SORT_GRAN || CPU_CORES == 1) {
sort(a, fromIndex, toIndex);
return;
}
final Queue> subArrayIndexQueue = new LinkedList<>();
final AtomicInteger activeThreadNum = new AtomicInteger();
final Holder errorHolder = new Holder<>();
final int lenOfSubArray = len % CPU_CORES == 0 ? len / CPU_CORES : (len / CPU_CORES) + 1;
for (int i = 0; i < CPU_CORES; i++) {
final int start = fromIndex + i * lenOfSubArray;
final int end = toIndex - start < lenOfSubArray ? toIndex : start + lenOfSubArray;
subArrayIndexQueue.add(Pair.of(start, end));
activeThreadNum.incrementAndGet();
parallelSortExecutor.execute(new Runnable() {
@Override
public void run() {
try {
if (errorHolder.value() != null) {
return;
}
Arrays.sort(a, start, end);
} catch (Exception e) {
setError(errorHolder, e);
} finally {
activeThreadNum.decrementAndGet();
}
}
});
}
while (activeThreadNum.get() > 0) {
N.sleep(1);
}
if (errorHolder.value() != null) {
throw N.toRuntimeException(errorHolder.value());
}
while (subArrayIndexQueue.size() > 1 && errorHolder.value() == null) {
for (int i = 0, size = subArrayIndexQueue.size(); i < size;) {
final Pair pairA = subArrayIndexQueue.poll();
if (++i == size) {
subArrayIndexQueue.add(pairA);
} else {
i++;
final Pair pairB = subArrayIndexQueue.poll();
subArrayIndexQueue.offer(Pair.of(pairA.left, pairB.right));
activeThreadNum.incrementAndGet();
parallelSortExecutor.execute(new Runnable() {
@Override
public void run() {
try {
if (errorHolder.value() != null) {
return;
}
merge(N.copyOfRange(a, pairA.left, pairA.right), 0, pairA.right - pairA.left, a, pairB.left, pairB.right, pairA.left);
} catch (Exception e) {
setError(errorHolder, e);
} finally {
activeThreadNum.decrementAndGet();
}
}
});
}
}
while (activeThreadNum.get() > 0) {
N.sleep(1);
}
if (errorHolder.value() != null) {
throw N.toRuntimeException(errorHolder.value());
}
}
if (errorHolder.value() != null) {
throw N.toRuntimeException(errorHolder.value());
}
}
static void merge(final float[] a, int fromIndexA, int toIndexA, final float[] b, int fromIndexB, int toIndexB, int fromIndex) {
int numOfNaN = 0;
for (int i = toIndexA - 1; i >= fromIndexA && Float.isNaN(a[i]); i--) {
toIndexA--;
numOfNaN++;
}
for (int i = toIndexB - 1; i >= fromIndexB && Float.isNaN(b[i]); i--) {
toIndexB--;
numOfNaN++;
}
while (fromIndexA < toIndexA && fromIndexB < toIndexB) {
if (Float.compare(a[fromIndexA], b[fromIndexB]) <= 0) {
b[fromIndex++] = a[fromIndexA++];
} else {
b[fromIndex++] = b[fromIndexB++];
}
}
if (fromIndexA < toIndexA) {
N.copy(a, fromIndexA, b, fromIndex, toIndexA - fromIndexA);
fromIndex += toIndexA - fromIndexA;
} else if (fromIndexB < toIndexB && numOfNaN > 0) {
N.copy(b, fromIndexB, b, fromIndex, toIndexB - fromIndexB);
fromIndex += toIndexB - fromIndexB;
}
if (numOfNaN > 0) {
N.fill(b, fromIndex, fromIndex + numOfNaN, Float.NaN);
}
}
static void parallelSort(final double[] array) {
if (N.isNullOrEmpty(array)) {
return;
}
parallelSort(array, 0, array.length);
}
static void parallelSort(final double[] a, final int fromIndex, final int toIndex) {
N.checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length);
if (N.isNullOrEmpty(a) || fromIndex == toIndex) {
return;
}
final int len = toIndex - fromIndex;
if (len < MIN_ARRAY_SORT_GRAN || CPU_CORES == 1) {
sort(a, fromIndex, toIndex);
return;
}
final Queue> subArrayIndexQueue = new LinkedList<>();
final AtomicInteger activeThreadNum = new AtomicInteger();
final Holder errorHolder = new Holder<>();
final int lenOfSubArray = len % CPU_CORES == 0 ? len / CPU_CORES : (len / CPU_CORES) + 1;
for (int i = 0; i < CPU_CORES; i++) {
final int start = fromIndex + i * lenOfSubArray;
final int end = toIndex - start < lenOfSubArray ? toIndex : start + lenOfSubArray;
subArrayIndexQueue.add(Pair.of(start, end));
activeThreadNum.incrementAndGet();
parallelSortExecutor.execute(new Runnable() {
@Override
public void run() {
try {
if (errorHolder.value() != null) {
return;
}
Arrays.sort(a, start, end);
} catch (Exception e) {
setError(errorHolder, e);
} finally {
activeThreadNum.decrementAndGet();
}
}
});
}
while (activeThreadNum.get() > 0) {
N.sleep(1);
}
if (errorHolder.value() != null) {
throw N.toRuntimeException(errorHolder.value());
}
while (subArrayIndexQueue.size() > 1 && errorHolder.value() == null) {
for (int i = 0, size = subArrayIndexQueue.size(); i < size;) {
final Pair pairA = subArrayIndexQueue.poll();
if (++i == size) {
subArrayIndexQueue.add(pairA);
} else {
i++;
final Pair pairB = subArrayIndexQueue.poll();
subArrayIndexQueue.offer(Pair.of(pairA.left, pairB.right));
activeThreadNum.incrementAndGet();
parallelSortExecutor.execute(new Runnable() {
@Override
public void run() {
try {
if (errorHolder.value() != null) {
return;
}
merge(N.copyOfRange(a, pairA.left, pairA.right), 0, pairA.right - pairA.left, a, pairB.left, pairB.right, pairA.left);
} catch (Exception e) {
setError(errorHolder, e);
} finally {
activeThreadNum.decrementAndGet();
}
}
});
}
}
while (activeThreadNum.get() > 0) {
N.sleep(1);
}
if (errorHolder.value() != null) {
throw N.toRuntimeException(errorHolder.value());
}
}
if (errorHolder.value() != null) {
throw N.toRuntimeException(errorHolder.value());
}
}
static void merge(final double[] a, int fromIndexA, int toIndexA, final double[] b, int fromIndexB, int toIndexB, int fromIndex) {
int numOfNaN = 0;
for (int i = toIndexA - 1; i >= fromIndexA && Double.isNaN(a[i]); i--) {
toIndexA--;
numOfNaN++;
}
for (int i = toIndexB - 1; i >= fromIndexB && Double.isNaN(b[i]); i--) {
toIndexB--;
numOfNaN++;
}
while (fromIndexA < toIndexA && fromIndexB < toIndexB) {
if (Double.compare(a[fromIndexA], b[fromIndexB]) <= 0) {
b[fromIndex++] = a[fromIndexA++];
} else {
b[fromIndex++] = b[fromIndexB++];
}
}
if (fromIndexA < toIndexA) {
N.copy(a, fromIndexA, b, fromIndex, toIndexA - fromIndexA);
fromIndex += toIndexA - fromIndexA;
} else if (fromIndexB < toIndexB && numOfNaN > 0) {
N.copy(b, fromIndexB, b, fromIndex, toIndexB - fromIndexB);
fromIndex += toIndexB - fromIndexB;
}
if (numOfNaN > 0) {
N.fill(b, fromIndex, fromIndex + numOfNaN, Double.NaN);
}
}
static void parallelSort(final Object[] a) {
if (N.isNullOrEmpty(a)) {
return;
}
parallelSort(a, 0, a.length);
}
static void parallelSort(final Object[] a, final int fromIndex, final int toIndex) {
parallelSort(a, fromIndex, toIndex, Comparators.NATURAL_ORDER);
}
static void parallelSort(final T[] a, final Comparator super T> cmp) {
if (N.isNullOrEmpty(a)) {
return;
}
parallelSort(a, 0, a.length, cmp);
}
static void parallelSort(final T[] a, final int fromIndex, final int toIndex, Comparator super T> cmp) {
N.checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length);
if (N.isNullOrEmpty(a) || fromIndex == toIndex) {
return;
}
final Comparator super T> comparator = cmp == null ? Comparators.NATURAL_ORDER : cmp;
final int len = toIndex - fromIndex;
if (len < MIN_ARRAY_SORT_GRAN || CPU_CORES == 1) {
sort(a, fromIndex, toIndex, comparator);
return;
}
final Queue> subArrayIndexQueue = new LinkedList<>();
final AtomicInteger activeThreadNum = new AtomicInteger();
final Holder errorHolder = new Holder<>();
final int lenOfSubArray = len % CPU_CORES == 0 ? len / CPU_CORES : (len / CPU_CORES) + 1;
for (int i = 0; i < CPU_CORES; i++) {
final int start = fromIndex + i * lenOfSubArray;
final int end = toIndex - start < lenOfSubArray ? toIndex : start + lenOfSubArray;
subArrayIndexQueue.add(Pair.of(start, end));
activeThreadNum.incrementAndGet();
parallelSortExecutor.execute(new Runnable() {
@Override
public void run() {
try {
if (errorHolder.value() != null) {
return;
}
Arrays.sort(a, start, end, comparator);
} catch (Exception e) {
setError(errorHolder, e);
} finally {
activeThreadNum.decrementAndGet();
}
}
});
}
while (activeThreadNum.get() > 0) {
N.sleep(1);
}
if (errorHolder.value() != null) {
throw N.toRuntimeException(errorHolder.value());
}
while (subArrayIndexQueue.size() > 1 && errorHolder.value() == null) {
for (int i = 0, size = subArrayIndexQueue.size(); i < size;) {
final Pair pairA = subArrayIndexQueue.poll();
if (++i == size) {
subArrayIndexQueue.add(pairA);
} else {
i++;
final Pair pairB = subArrayIndexQueue.poll();
subArrayIndexQueue.offer(Pair.of(pairA.left, pairB.right));
activeThreadNum.incrementAndGet();
parallelSortExecutor.execute(new Runnable() {
@Override
public void run() {
try {
if (errorHolder.value() != null) {
return;
}
merge(N.copyOfRange(a, pairA.left, pairA.right), 0, pairA.right - pairA.left, a, pairB.left, pairB.right, pairA.left,
comparator);
} catch (Exception e) {
setError(errorHolder, e);
} finally {
activeThreadNum.decrementAndGet();
}
}
});
}
}
while (activeThreadNum.get() > 0) {
N.sleep(1);
}
if (errorHolder.value() != null) {
throw N.toRuntimeException(errorHolder.value());
}
}
if (errorHolder.value() != null) {
throw N.toRuntimeException(errorHolder.value());
}
}
static void merge(final T[] a, int fromIndexA, int toIndexA, final T[] b, int fromIndexB, int toIndexB, int fromIndex, Comparator super T> cmp) {
while (fromIndexA < toIndexA && fromIndexB < toIndexB) {
if (cmp.compare(a[fromIndexA], b[fromIndexB]) <= 0) {
b[fromIndex++] = a[fromIndexA++];
} else {
b[fromIndex++] = b[fromIndexB++];
}
}
if (fromIndexA < toIndexA) {
N.copy(a, fromIndexA, b, fromIndex, toIndexA - fromIndexA);
fromIndex += toIndexA - fromIndexA;
}
}
static > void parallelSort(final List extends T> c) {
if (N.isNullOrEmpty(c)) {
return;
}
parallelSort(c, 0, c.size());
}
static > void parallelSort(final List extends T> c, final int fromIndex, final int toIndex) {
parallelSort(c, fromIndex, toIndex, Comparators.NATURAL_ORDER);
}
static void parallelSort(final List extends T> list, final Comparator super T> cmp) {
if (N.isNullOrEmpty(list)) {
return;
}
parallelSort(list, 0, list.size(), cmp);
}
@SuppressWarnings("rawtypes")
static void parallelSort(final List extends T> c, final int fromIndex, final int toIndex, final Comparator super T> cmp) {
if ((N.isNullOrEmpty(c) && fromIndex == 0 && toIndex == 0) || fromIndex == toIndex) {
return;
}
if (N.isListElementDataFieldGettable && N.listElementDataField != null && c instanceof ArrayList) {
T[] array = null;
try {
array = (T[]) N.listElementDataField.get(c);
} catch (Exception e) {
// ignore;
N.isListElementDataFieldGettable = false;
}
if (array != null) {
parallelSort(array, fromIndex, toIndex, cmp);
return;
}
}
final T[] array = (T[]) c.toArray();
parallelSort(array, fromIndex, toIndex, cmp);
final ListIterator