All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.landawn.abacus.util.CommonUtil Maven / Gradle / Ivy

Go to download

A general programming library in Java/Android. It's easy to learn and simple to use with concise and powerful APIs.

The newest version!
/*
 * Copyright (c) 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
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.landawn.abacus.util;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.SQLException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.AbstractMap;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Deque;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.NavigableMap;
import java.util.NavigableSet;
import java.util.Objects;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Random;
import java.util.RandomAccess;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.function.ToDoubleFunction;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
import java.util.function.UnaryOperator;

import com.landawn.abacus.annotation.Beta;
import com.landawn.abacus.annotation.Immutable;
import com.landawn.abacus.annotation.Internal;
import com.landawn.abacus.annotation.MayReturnNull;
import com.landawn.abacus.annotation.NotNull;
import com.landawn.abacus.annotation.NullSafe;
import com.landawn.abacus.annotation.SuppressFBWarnings;
import com.landawn.abacus.exception.TooManyElementsException;
import com.landawn.abacus.exception.UncheckedSQLException;
import com.landawn.abacus.parser.ParserUtil;
import com.landawn.abacus.parser.ParserUtil.BeanInfo;
import com.landawn.abacus.parser.ParserUtil.PropInfo;
import com.landawn.abacus.type.Type;
import com.landawn.abacus.type.TypeFactory;
import com.landawn.abacus.util.Builder.ComparisonBuilder;
import com.landawn.abacus.util.Fn.BiPredicates;
import com.landawn.abacus.util.Fn.IntFunctions;
import com.landawn.abacus.util.Fn.Suppliers;
import com.landawn.abacus.util.u.Nullable;
import com.landawn.abacus.util.u.Optional;
import com.landawn.abacus.util.u.OptionalInt;
import com.landawn.abacus.util.function.ToFloatFunction;

/**
 * 

* Note: This class includes codes copied from Apache Commons Lang, Google Guava and other open source projects under the Apache License 2.0. * The methods copied from other libraries/frameworks/projects may be modified in this class. *

* Class {@code N} is a general java utility class. It provides the most daily used operations for Object/primitive types/String/Array/Collection/Map/Bean...: * *
*
* When to throw exception? It's designed to avoid throwing any unnecessary * exception if the contract defined by method is not broken. For example, if * user tries to reverse a {@code null} or empty String. The input String will be * returned. But exception will be thrown if try to add element to a {@code null} Object array or collection. *
*
* An empty String/Array/Collection/Map/Iterator/Iterable/InputStream/Reader will always be a preferred choice than a {@code null} for the return value of a method. *
* There are only {@code fromIndex/startIndex} and {toIndex/endIndex} parameters in the methods defined in class {@code CommonUtil/N}, no {@code offset/count} parameters. *
* * @see com.landawn.abacus.util.Comparators * @see com.landawn.abacus.util.Fn * @see com.landawn.abacus.util.Fn.Fnn * @see com.landawn.abacus.util.Array * @see com.landawn.abacus.util.CommonUtil * @see com.landawn.abacus.util.Iterables * @see com.landawn.abacus.util.Iterators * @see com.landawn.abacus.util.Index * @see com.landawn.abacus.util.Median * @see com.landawn.abacus.util.Maps * @see com.landawn.abacus.util.Strings * @see com.landawn.abacus.util.Numbers * @see com.landawn.abacus.util.IOUtil * @see java.lang.reflect.Array * @see java.util.Arrays * @see java.util.Collections * * @version $Revision: 0.8 $ 07/03/10 */ @SuppressWarnings({ "java:S1192", "java:S6539" }) sealed class CommonUtil permits N { static final int BINARY_SEARCH_THRESHOLD = 64; // ... static final int REVERSE_THRESHOLD = 18; static final int FILL_THRESHOLD = 25; static final int REPLACE_ALL_THRESHOLD = 11; static final int MIN_SIZE_FOR_COPY_ALL = 9; static final int DEFAULT_SIZE_FOR_NEW_COLLECTION = 9; // ... static final Random RAND = new SecureRandom(); // ... it has to be big enough to make it's safety to add element to // ArrayBlockingQueue. @SuppressWarnings("deprecation") static final int POOL_SIZE = InternalUtil.POOL_SIZE; // ... /** * The index value when an element is not found in a list or array: * {@code -1}. This value is returned by methods in this class and can also * be used in comparisons with values returned by various method from * {@link java.util.List} . */ public static final int INDEX_NOT_FOUND = -1; /** * An empty immutable/unmodifiable {@code boolean} array. */ public static final boolean[] EMPTY_BOOLEAN_ARRAY = {}; /** * An empty immutable/unmodifiable {@code char} array. */ public static final char[] EMPTY_CHAR_ARRAY = {}; /** * An empty immutable/unmodifiable {@code byte} array. */ public static final byte[] EMPTY_BYTE_ARRAY = {}; /** * An empty immutable/unmodifiable {@code short} array. */ public static final short[] EMPTY_SHORT_ARRAY = {}; /** * An empty immutable/unmodifiable {@code int} array. */ public static final int[] EMPTY_INT_ARRAY = {}; /** * An empty immutable/unmodifiable {@code long} array. */ public static final long[] EMPTY_LONG_ARRAY = {}; /** * An empty immutable/unmodifiable {@code float} array. */ public static final float[] EMPTY_FLOAT_ARRAY = {}; /** * An empty immutable/unmodifiable {@code double} array. */ public static final double[] EMPTY_DOUBLE_ARRAY = {}; /** * An empty immutable/unmodifiable {@code Boolean} array. */ public static final Boolean[] EMPTY_BOOLEAN_OBJ_ARRAY = {}; /** * An empty immutable/unmodifiable {@code Character} array. */ public static final Character[] EMPTY_CHAR_OBJ_ARRAY = {}; /** * An empty immutable/unmodifiable {@code Byte} array. */ public static final Byte[] EMPTY_BYTE_OBJ_ARRAY = {}; /** * An empty immutable/unmodifiable {@code Short} array. */ public static final Short[] EMPTY_SHORT_OBJ_ARRAY = {}; /** * An empty immutable/unmodifiable {@code Integer} array. */ public static final Integer[] EMPTY_INT_OBJ_ARRAY = {}; /** * An empty immutable/unmodifiable {@code Long} array. */ public static final Long[] EMPTY_LONG_OBJ_ARRAY = {}; /** * An empty immutable/unmodifiable {@code Float} array. */ public static final Float[] EMPTY_FLOAT_OBJ_ARRAY = {}; /** * An empty immutable/unmodifiable {@code Double} array. */ public static final Double[] EMPTY_DOUBLE_OBJ_ARRAY = {}; /** * An empty immutable/unmodifiable {@code BigInteger} array. */ public static final BigInteger[] EMPTY_BIG_INTEGER_ARRAY = {}; /** * An empty immutable/unmodifiable {@code BigDecimal} array. */ public static final BigDecimal[] EMPTY_BIG_DECIMAL_ARRAY = {}; /** * An empty immutable/unmodifiable {@code String} array. */ public static final String[] EMPTY_STRING_ARRAY = {}; /** * An empty immutable/unmodifiable {@code java.util.Date} array. */ public static final java.util.Date[] EMPTY_JU_DATE_ARRAY = {}; /** * An empty immutable/unmodifiable {@code java.sql.Date} array. */ public static final java.sql.Date[] EMPTY_DATE_ARRAY = {}; /** * An empty immutable/unmodifiable {@code Time} array. */ public static final java.sql.Time[] EMPTY_TIME_ARRAY = {}; /** * An empty immutable/unmodifiable {@code Timestamp} array. */ public static final java.sql.Timestamp[] EMPTY_TIMESTAMP_ARRAY = {}; /** * An empty immutable/unmodifiable {@code Calendar} array. */ @SuppressFBWarnings("STCAL_STATIC_CALENDAR_INSTANCE") public static final Calendar[] EMPTY_CALENDAR_ARRAY = {}; /** * An empty immutable/unmodifiable {@code LocalDate} array. */ public static final LocalDate[] EMPTY_LOCAL_DATE_ARRAY = {}; /** * An empty immutable/unmodifiable {@code LocalTime} array. */ public static final LocalTime[] EMPTY_LOCAL_TIME_ARRAY = {}; /** * An empty immutable/unmodifiable {@code LocalDateTime} array. */ public static final LocalDateTime[] EMPTY_LOCAL_DATE_TIME_ARRAY = {}; /** * An empty immutable/unmodifiable {@code Object} array. */ public static final Object[] EMPTY_OBJECT_ARRAY = {}; // /** // * An empty immutable/unmodifiable {@code DataSet}. // */ // public static final DataSet EMPTY_DATA_SET = RowDataSet.EMPTY_DATA_SET; /** * An empty immutable/unmodifiable {@code Class} array. */ static final Class[] EMPTY_CLASS_ARRAY = new Class[0]; /** * An empty immutable/unmodifiable {@code List}. */ @SuppressWarnings("rawtypes") static final List EMPTY_LIST = Collections.emptyList(); /** * An empty immutable/unmodifiable {@code Set}. */ @SuppressWarnings("rawtypes") static final Set EMPTY_SET = Collections.emptySet(); /** * An empty immutable/unmodifiable {@code SortedSet}. */ @SuppressWarnings("rawtypes") static final SortedSet EMPTY_SORTED_SET = Collections.emptySortedSet(); /** * An empty immutable/unmodifiable {@code NavigableSet}. */ @SuppressWarnings("rawtypes") static final NavigableSet EMPTY_NAVIGABLE_SET = Collections.emptyNavigableSet(); /** * An empty immutable/unmodifiable {@code Map}. */ @SuppressWarnings("rawtypes") static final Map EMPTY_MAP = Collections.emptyMap(); /** * An empty immutable/unmodifiable {@code SortedMap}. */ @SuppressWarnings("rawtypes") static final SortedMap EMPTY_SORTED_MAP = Collections.emptySortedMap(); /** * An empty immutable/unmodifiable {@code NavigableMap}. */ @SuppressWarnings("rawtypes") static final NavigableMap EMPTY_NAVIGABLE_MAP = Collections.emptyNavigableMap(); /** * An empty immutable/unmodifiable iterator. */ @SuppressWarnings("rawtypes") static final Iterator EMPTY_ITERATOR = Collections.emptyIterator(); /** * An empty immutable/unmodifiable {@code ListIterator}. */ @SuppressWarnings("rawtypes") static final ListIterator EMPTY_LIST_ITERATOR = Collections.emptyListIterator(); @SuppressWarnings("rawtypes") static final Comparator NULL_MIN_COMPARATOR = Comparators.NULL_FIRST_COMPARATOR; @SuppressWarnings("rawtypes") static final Comparator NULL_MAX_COMPARATOR = Comparators.NULL_LAST_COMPARATOR; @SuppressWarnings("rawtypes") static final Comparator NATURAL_COMPARATOR = Comparators.NATURAL_ORDER; @SuppressWarnings("rawtypes") static final Comparator REVERSED_COMPARATOR = Comparators.REVERSED_ORDER; static final Comparator CHAR_COMPARATOR = Character::compare; static final Comparator BYTE_COMPARATOR = Byte::compare; static final Comparator SHORT_COMPARATOR = Short::compare; static final Comparator INT_COMPARATOR = Integer::compare; static final Comparator LONG_COMPARATOR = Long::compare; static final Comparator FLOAT_COMPARATOR = Float::compare; static final Comparator DOUBLE_COMPARATOR = Double::compare; // ... static final Object NULL_MASK = ClassUtil.createNullMask(); // ... static final Map, Object> CLASS_EMPTY_ARRAY = new ConcurrentHashMap<>(); static { CLASS_EMPTY_ARRAY.put(boolean.class, EMPTY_BOOLEAN_ARRAY); CLASS_EMPTY_ARRAY.put(Boolean.class, EMPTY_BOOLEAN_OBJ_ARRAY); CLASS_EMPTY_ARRAY.put(char.class, EMPTY_CHAR_ARRAY); CLASS_EMPTY_ARRAY.put(Character.class, EMPTY_CHAR_OBJ_ARRAY); CLASS_EMPTY_ARRAY.put(byte.class, EMPTY_BYTE_ARRAY); CLASS_EMPTY_ARRAY.put(Byte.class, EMPTY_BYTE_OBJ_ARRAY); CLASS_EMPTY_ARRAY.put(short.class, EMPTY_SHORT_ARRAY); CLASS_EMPTY_ARRAY.put(Short.class, EMPTY_SHORT_OBJ_ARRAY); CLASS_EMPTY_ARRAY.put(int.class, EMPTY_INT_ARRAY); CLASS_EMPTY_ARRAY.put(Integer.class, EMPTY_INT_OBJ_ARRAY); CLASS_EMPTY_ARRAY.put(long.class, EMPTY_LONG_ARRAY); CLASS_EMPTY_ARRAY.put(Long.class, EMPTY_LONG_OBJ_ARRAY); CLASS_EMPTY_ARRAY.put(float.class, EMPTY_FLOAT_ARRAY); CLASS_EMPTY_ARRAY.put(Float.class, EMPTY_FLOAT_OBJ_ARRAY); CLASS_EMPTY_ARRAY.put(double.class, EMPTY_DOUBLE_ARRAY); CLASS_EMPTY_ARRAY.put(Double.class, EMPTY_DOUBLE_OBJ_ARRAY); CLASS_EMPTY_ARRAY.put(String.class, EMPTY_STRING_ARRAY); CLASS_EMPTY_ARRAY.put(Object.class, EMPTY_OBJECT_ARRAY); } // ... static final Map, Integer> CLASS_TYPE_ENUM = new HashMap<>(); static { CLASS_TYPE_ENUM.put(boolean.class, 1); CLASS_TYPE_ENUM.put(char.class, 2); CLASS_TYPE_ENUM.put(byte.class, 3); CLASS_TYPE_ENUM.put(short.class, 4); CLASS_TYPE_ENUM.put(int.class, 5); CLASS_TYPE_ENUM.put(long.class, 6); CLASS_TYPE_ENUM.put(float.class, 7); CLASS_TYPE_ENUM.put(double.class, 8); CLASS_TYPE_ENUM.put(String.class, 9); CLASS_TYPE_ENUM.put(boolean[].class, 11); CLASS_TYPE_ENUM.put(char[].class, 12); CLASS_TYPE_ENUM.put(byte[].class, 13); CLASS_TYPE_ENUM.put(short[].class, 14); CLASS_TYPE_ENUM.put(int[].class, 15); CLASS_TYPE_ENUM.put(long[].class, 16); CLASS_TYPE_ENUM.put(float[].class, 17); CLASS_TYPE_ENUM.put(double[].class, 18); CLASS_TYPE_ENUM.put(String[].class, 19); CLASS_TYPE_ENUM.put(Boolean.class, 21); CLASS_TYPE_ENUM.put(Character.class, 22); CLASS_TYPE_ENUM.put(Byte.class, 23); CLASS_TYPE_ENUM.put(Short.class, 24); CLASS_TYPE_ENUM.put(Integer.class, 25); CLASS_TYPE_ENUM.put(Long.class, 26); CLASS_TYPE_ENUM.put(Float.class, 27); CLASS_TYPE_ENUM.put(Double.class, 28); } // ... private static final Map>, ImmutableList>> enumListPool = new ObjectPool<>(POOL_SIZE); private static final Map>, ImmutableSet>> enumSetPool = new ObjectPool<>(POOL_SIZE); private static final Map>, ImmutableBiMap, String>> enumMapPool = new ObjectPool<>(POOL_SIZE); private static final Map> nameTypePool = new ObjectPool<>(POOL_SIZE); private static final Map, Type> clsTypePool = new ObjectPool<>(POOL_SIZE); static final String[] charStringCache = new String[128]; static final int intStringCacheLow = -1001; static final int intStringCacheHigh = 10001; static final String[] intStringCache = new String[intStringCacheHigh - intStringCacheLow]; static final Map stringIntCache = new HashMap<>((int) (intStringCache.length * 1.5)); static { for (int i = 0, j = intStringCacheLow, len = intStringCache.length; i < len; i++, j++) { intStringCache[i] = Integer.toString(j); stringIntCache.put(intStringCache[i], j); } for (int i = 0; i < charStringCache.length; i++) { charStringCache[i] = String.valueOf((char) i); } } CommonUtil() { // Utility class. } /** * Gets a Type by the given type name. * * @param typeName the name of the type to be retrieved. * @return the Type corresponding to the given type name. * @throws IllegalArgumentException if the specified {@code typeName} is {@code null}. */ @SuppressWarnings("unchecked") public static Type typeOf(@NotNull final String typeName) throws IllegalArgumentException { checkArgNotNull(typeName, cs.typeName); Type type = nameTypePool.get(typeName); if (type == null) { type = TypeFactory.getType(typeName); nameTypePool.put(typeName, type); } return (Type) type; } /** * Gets a Type by the given {@code Class}. * * @param cls the name of the type to be retrieved. * @return the Type corresponding to the given type name. * @throws IllegalArgumentException if the specified {@code Class} is {@code null}. */ @SuppressWarnings("unchecked") public static Type typeOf(@NotNull final Class cls) throws IllegalArgumentException { checkArgNotNull(cls, cs.cls); Type type = clsTypePool.get(cls); if (type == null) { type = TypeFactory.getType(cls); clsTypePool.put(cls, type); } return (Type) type; } /** * Returns the default value of the given class type. * * @param * @param cls the class type for which the default value is to be returned. * @return the default value of the given class type. For example, for an Integer class type, it will return 0. * @throws IllegalArgumentException if the specified class type is {@code null}. */ @SuppressWarnings("unchecked") public static T defaultValueOf(final Class cls) { return (T) typeOf(cls).defaultValue(); } /** * Returns the default value of the given type if the specified object is {@code null} or itself if the specified object is not {@code null}. * * @param b * @return */ public static boolean defaultIfNull(final Boolean b) { if (b == null) { return false; } return b; } /** * Returns the specified default value if the specified object is {@code null} or itself if the specified object is not {@code null}. * * @param b * @param defaultForNull * @return */ public static boolean defaultIfNull(final Boolean b, final boolean defaultForNull) { if (b == null) { return defaultForNull; } return b; } /** * Returns the default value of the given type if the specified object is {@code null} or itself if the specified object is not {@code null}. * * @param c * @return */ public static char defaultIfNull(final Character c) { if (c == null) { return Strings.CHAR_ZERO; } return c; } /** * Returns the specified default value if the specified object is {@code null} or itself if the specified object is not {@code null}. * * @param c * @param defaultForNull * @return */ public static char defaultIfNull(final Character c, final char defaultForNull) { if (c == null) { return defaultForNull; } return c; } /** * Returns the default value of the given type if the specified object is {@code null} or itself if the specified object is not {@code null}. * * @param b * @return */ public static byte defaultIfNull(final Byte b) { if (b == null) { return (byte) 0; } return b; } /** * Returns the specified default value if the specified object is {@code null} or itself if the specified object is not {@code null}. * * @param b * @param defaultForNull * @return */ public static byte defaultIfNull(final Byte b, final byte defaultForNull) { if (b == null) { return defaultForNull; } return b; } /** * Returns the default value of the given type if the specified object is {@code null} or itself if the specified object is not {@code null}. * * @param b * @return */ public static short defaultIfNull(final Short b) { if (b == null) { return (short) 0; } return b; } /** * Returns the specified default value if the specified object is {@code null} or itself if the specified object is not {@code null}. * * @param b * @param defaultForNull * @return */ public static short defaultIfNull(final Short b, final short defaultForNull) { if (b == null) { return defaultForNull; } return b; } /** * Returns the default value of the given type if the specified object is {@code null} or itself if the specified object is not {@code null}. * * @param b * @return */ public static int defaultIfNull(final Integer b) { if (b == null) { return 0; } return b; } /** * Returns the specified default value if the specified object is {@code null} or itself if the specified object is not {@code null}. * * @param b * @param defaultForNull * @return */ public static int defaultIfNull(final Integer b, final int defaultForNull) { if (b == null) { return defaultForNull; } return b; } /** * Returns the default value of the given type if the specified object is {@code null} or itself if the specified object is not {@code null}. * * @param b * @return */ public static long defaultIfNull(final Long b) { if (b == null) { return 0; } return b; } /** * Returns the specified default value if the specified object is {@code null} or itself if the specified object is not {@code null}. * * @param b * @param defaultForNull * @return */ public static long defaultIfNull(final Long b, final long defaultForNull) { if (b == null) { return defaultForNull; } return b; } /** * Returns the default value of the given type if the specified object is {@code null} or itself if the specified object is not {@code null}. * * @param b * @return */ public static float defaultIfNull(final Float b) { if (b == null) { return 0; } return b; } /** * Returns the specified default value if the specified object is {@code null} or itself if the specified object is not {@code null}. * * @param b * @param defaultForNull * @return */ public static float defaultIfNull(final Float b, final float defaultForNull) { if (b == null) { return defaultForNull; } return b; } /** * Returns the default value of the given type if the specified object is {@code null} or itself if the specified object is not {@code null}. * * @param b * @return */ public static double defaultIfNull(final Double b) { if (b == null) { return 0; } return b; } /** * Returns the specified default value if the specified object is {@code null} or itself if the specified object is not {@code null}. * * @param b * @param defaultForNull * @return */ public static double defaultIfNull(final Double b, final double defaultForNull) { if (b == null) { return defaultForNull; } return b; } /** * Returns the specified default value if the given object is {@code null}, otherwise returns the object itself. * * @param the type of the object * @param obj the object to check for {@code null} * @param defaultForNull the default value to return if {@code obj} is {@code null} * @return {@code obj} if it is not {@code null}, otherwise {@code defaultForNull} * @throws IllegalArgumentException if the specified default value is {@code null}. * @see Strings#defaultIfNull(CharSequence, CharSequence) */ public static T defaultIfNull(final T obj, final T defaultForNull) throws IllegalArgumentException { checkArgNotNull(defaultForNull, cs.defaultValue); return obj == null ? defaultForNull : obj; } /** * Returns the default value provided by specified {@code Supplier} if the specified object is {@code null}, otherwise returns the object itself. * * @param * @param obj * @param supplierForDefault * @return * @throws IllegalArgumentException if default value provided by specified {@code Supplier} is {@code null} when the specified object is {@code null}. * @see Strings#defaultIfNull(CharSequence, Supplier) */ public static T defaultIfNull(final T obj, final Supplier supplierForDefault) throws IllegalArgumentException { if (obj == null) { return checkArgNotNull(supplierForDefault.get(), cs.defaultValue); } return obj; } /** * Returns the specified default value if the specified {@code charSequence} is empty, otherwise returns the {@code charSequence} itself. * * @param * @param str * @param defaultForEmpty * @return * @throws IllegalArgumentException if the specified default charSequence value is empty. * @see Strings#defaultIfEmpty(CharSequence, CharSequence) */ public static T defaultIfEmpty(final T str, final T defaultForEmpty) throws IllegalArgumentException { checkArgNotEmpty(defaultForEmpty, cs.defaultValue); return isEmpty(str) ? defaultForEmpty : str; } /** * Returns the default value provided by specified {@code Supplier} if the specified {@code charSequence} is empty, otherwise returns the {@code charSequence} itself. * * @param * @param str * @param supplierForDefault * @return * @throws IllegalArgumentException if default value provided by specified {@code Supplier} is empty when the specified {@code charSequence} is empty. * @see Strings#defaultIfEmpty(CharSequence, Supplier) */ public static T defaultIfEmpty(final T str, final Supplier supplierForDefault) { if (isEmpty(str)) { return checkArgNotEmpty(supplierForDefault.get(), cs.defaultValue); } return str; } /** * Returns the specified default value if the specified {@code charSequence} is blank, otherwise returns the {@code charSequence} itself. * * @param * @param str * @param defaultForBlank * @return * @throws IllegalArgumentException if the specified default charSequence value is bank. * @see Strings#defaultIfBlank(CharSequence, CharSequence) */ public static T defaultIfBlank(final T str, final T defaultForBlank) throws IllegalArgumentException { checkArgNotBlank(defaultForBlank, cs.defaultValue); return isBlank(str) ? defaultForBlank : str; } /** * Returns the default value provided by specified {@code Supplier} if the specified {@code charSequence} is blank, otherwise returns the {@code charSequence} itself. * * @param * @param str * @param supplierForDefault * @return * @throws IllegalArgumentException if default value provided by specified {@code Supplier} is blank when the specified {@code charSequence} is blank. * @see Strings#defaultIfBlank(CharSequence, Supplier) */ public static T defaultIfBlank(final T str, final Supplier supplierForDefault) { if (isBlank(str)) { return checkArgNotBlank(supplierForDefault.get(), cs.defaultValue); } return str; } /** * Returns the specified default value if the specified Collection is empty, otherwise returns the {@code Collection} itself. * * @param * @param c * @param defaultForEmpty * @return * @throws IllegalArgumentException if the specified default collection value is empty. */ public static > T defaultIfEmpty(final T c, final T defaultForEmpty) throws IllegalArgumentException { checkArgNotEmpty(defaultForEmpty, cs.defaultValue); return isEmpty(c) ? defaultForEmpty : c; } /** * Returns the specified default value if the specified Map is empty, otherwise returns the {@code Map} itself. * * @param * @param m * @param defaultForEmpty * @return * @throws IllegalArgumentException if the specified default map value is empty. */ public static > T defaultIfEmpty(final T m, final T defaultForEmpty) throws IllegalArgumentException { checkArgNotEmpty(defaultForEmpty, cs.defaultValue); return isEmpty(m) ? defaultForEmpty : m; } /** * Converts the given value to its corresponding String representation. * * @param val the value to be converted. * @return the String representation of the given value. Returns "true" if the value is {@code true}, "false" otherwise. */ public static String stringOf(final boolean val) { return val ? Strings.TRUE : Strings.FALSE; } /** * Converts the given value to its corresponding String representation. * * @param val the value to be converted. * @return the String representation of the given value. */ public static String stringOf(final char val) { if (val < 128) { return charStringCache[val]; } return String.valueOf(val); } /** * Converts the given value to its corresponding String representation. * * @param val the value to be converted. * @return the String representation of the given value. */ @SuppressFBWarnings({ "INT_BAD_COMPARISON_WITH_SIGNED_BYTE", "INT_BAD_COMPARISON_WITH_SIGNED_BYTE" }) public static String stringOf(final byte val) { //noinspection ConstantValue if (val > intStringCacheLow && val < intStringCacheHigh) { return intStringCache[val - intStringCacheLow]; } return String.valueOf(val); } /** * Converts the given value to its corresponding String representation. * * @param val the value to be converted. * @return the String representation of the given value. */ public static String stringOf(final short val) { if (val > intStringCacheLow && val < intStringCacheHigh) { return intStringCache[val - intStringCacheLow]; } return String.valueOf(val); } /** * Converts the given value to its corresponding String representation. * * @param val the value to be converted. * @return the String representation of the given value. */ public static String stringOf(final int val) { if (val > intStringCacheLow && val < intStringCacheHigh) { return intStringCache[val - intStringCacheLow]; } return String.valueOf(val); } /** * Converts the given value to its corresponding String representation. * * @param val the value to be converted. * @return the String representation of the given value. */ public static String stringOf(final long val) { if (val > intStringCacheLow && val < intStringCacheHigh) { return intStringCache[(int) (val - intStringCacheLow)]; } return String.valueOf(val); } /** * Converts the given value to its corresponding String representation. * * @param val the value to be converted. * @return the String representation of the given value. */ public static String stringOf(final float val) { return String.valueOf(val); } /** * Converts the given value to its corresponding String representation. * * @param val the value to be converted. * @return the String representation of the given value. */ public static String stringOf(final double val) { return String.valueOf(val); } /** * Converts the given value to its corresponding String representation by {@code Type.stringOf(Object)}. * * @param obj the value to be converted. * @return the String representation of the given value. {@code null} if the specified object is null * @see #valueOf(String, Class) * @see Type#stringOf(Object) */ public static String stringOf(final Object obj) { return (obj == null) ? null : typeOf(obj.getClass()).stringOf(obj); } /** * Converts the given string to its corresponding value of the specified target type by {@code typeOf(targetType).valueOf(str)}. * * @param The type of the target object after conversion. * @param str The string to be converted. * @param targetType The class of the target type to which the string is to be converted. * @return The converted value of the specified target type. If the input string is {@code null}, it returns the default value of the target type. * @throws IllegalArgumentException if the specified target type is {@code null}. * @see #stringOf(Object) * @see Type#valueOf(String) */ @SuppressWarnings("unchecked") public static T valueOf(final String str, final Class targetType) { return (str == null) ? defaultValueOf(targetType) : (T) typeOf(targetType).valueOf(str); } private static final Map, BiFunction, Object>> converterMap = new ConcurrentHashMap<>(); /** * Registers a converter for a specific source class. The converter is a function that takes an object of the source class * and a target class, and converts the source object into an instance of the target class. * * @param srcClass The source class that the converter can convert from. This must not be a built-in class. * @param converter The converter function that takes a source object and a target class, and returns an instance of the target class. * @return {@code true} if there is no {@code converter} registered with specified {@code srcClass} yet before this call. * @throws IllegalArgumentException if the specified {@code srcClass} is a built-in class or if either {@code srcClass} or {@code converter} is {@code null}. */ @SuppressWarnings("rawtypes") public static boolean registerConverter(@NotNull final Class srcClass, final BiFunction, ?> converter) throws IllegalArgumentException { checkArgNotNull(srcClass, cs.srcClass); checkArgNotNull(converter, cs.converter); if (isBuiltinClass(srcClass)) { throw new IllegalArgumentException("Can't register converter with builtin class: " + ClassUtil.getCanonicalClassName(srcClass)); } synchronized (converterMap) { if (converterMap.containsKey(srcClass)) { return false; } converterMap.put(srcClass, (BiFunction) converter); return true; } } static boolean isBuiltinClass(final Class cls) { final Package pkg = cls.getPackage(); if (pkg == null) { if (ClassUtil.isPrimitiveType(cls) || ClassUtil.isPrimitiveArrayType(cls)) { return true; } else if (cls.isArray()) { Class componentType = cls.getComponentType(); while (componentType.isArray()) { componentType = componentType.getComponentType(); } return ClassUtil.isPrimitiveType(cls) || ClassUtil.isPrimitiveArrayType(cls); } return false; } final String pkgName = pkg.getName(); return Strings.isNotEmpty(pkgName) && (pkgName.startsWith("java.") || pkgName.startsWith("javax.") || pkgName.startsWith("com.landawn.abacus.")); } /** * Converts the given source object to the specified target type. * If the source object is {@code null}, the default value of the target type is returned. * If the source object can be converted to the target type, an instance of the target type is returned. * * @param The type of the target object after conversion. * @param srcObj The source object to be converted. If {@code null}, the default value of the target type is returned. * @param targetType The class of the target type to which the source object is to be converted. * @return An instance of the target type converted from the source object, or the default value of the target type if the source object is {@code null}. * @throws IllegalArgumentException if the source object cannot be converted to the target type. * @throws NumberFormatException if string value of the source object cannot be parsed to the target(Number) type. * @throws RuntimeException if any other error occurs during the conversion. */ public static T convert(final Object srcObj, final Class targetType) throws IllegalArgumentException, NumberFormatException, RuntimeException { if (srcObj == null) { return defaultValueOf(targetType); } final Class srcClass = srcObj.getClass(); BiFunction, Object> converterFunc = null; if ((converterFunc = converterMap.get(srcClass)) != null) { return (T) converterFunc.apply(srcObj, targetType); } final Type type = typeOf(targetType); return convert(srcObj, srcClass, type); } /** * Converts the given source object to the specified target type using the provided Type instance. * If the source object is {@code null}, the default value of the target type is returned. * If the source object can be converted to the target type, an instance of the target type is returned. * * @param The type of the target object after conversion. * @param srcObj The source object to be converted. * @param targetType The Type instance of the target type to which the source object is to be converted. * @return An instance of the target type converted from the source object, or the default value of the target type if the source object is {@code null}. * @throws IllegalArgumentException if the source object cannot be converted to the target type. * @throws NumberFormatException if string value of the source object cannot be parsed to the target(Number) type. * @throws RuntimeException if any other error occurs during the conversion. */ public static T convert(final Object srcObj, final Type targetType) throws IllegalArgumentException, NumberFormatException, RuntimeException { if (srcObj == null) { return targetType.defaultValue(); } final Class srcClass = srcObj.getClass(); BiFunction, Object> converterFunc = null; if ((converterFunc = converterMap.get(srcClass)) != null) { return (T) converterFunc.apply(srcObj, targetType.clazz()); } return convert(srcObj, srcClass, targetType); } @SuppressWarnings({ "rawtypes" }) private static T convert(final Object srcObj, final Class srcClass, final Type targetType) { if (targetType.clazz().isAssignableFrom(srcClass)) { return (T) srcObj; } final Type srcType = typeOf(srcClass); if (targetType.isString()) { return (T) srcType.stringOf(srcObj); } else if (targetType.isNumber()) { if (srcType.isString()) { // fall through. } else if (srcType.isNumber()) { return (T) Numbers.convert((Number) srcObj, (Type) targetType); } else if (srcType.clazz().equals(Character.class) && (targetType.clazz().equals(int.class) || targetType.clazz().equals(Integer.class))) { return (T) (Integer.valueOf((Character) srcObj)); //NOSONAR } else if ((targetType.clazz().equals(long.class) || targetType.clazz().equals(Long.class)) && java.util.Date.class.isAssignableFrom(srcType.clazz())) { return (T) (Long) ((java.util.Date) srcObj).getTime(); } return targetType.valueOf(srcObj); } else if (targetType.isBoolean()) { if (srcType.isNumber()) { return (T) ((Boolean) (((Number) srcObj).longValue() > 0)); } else { return targetType.valueOf(srcObj); } } else if ((targetType.clazz().equals(char.class) || targetType.clazz().equals(Character.class))) { if (srcType.clazz().equals(Integer.class)) { return (T) (Character.valueOf((char) ((Integer) srcObj).intValue())); } else { return targetType.valueOf(srcObj); } } else if (srcType.clazz().equals(Long.class)) { if (targetType.clazz().equals(java.util.Date.class)) { return (T) new java.util.Date((Long) srcObj); } else if (targetType.clazz().equals(java.sql.Timestamp.class)) { return (T) new java.sql.Timestamp((Long) srcObj); } else if (targetType.clazz().equals(java.sql.Date.class)) { return (T) new java.sql.Date((Long) srcObj); } else if (targetType.clazz().equals(java.sql.Time.class)) { return (T) new java.sql.Time((Long) srcObj); } else { return targetType.valueOf(srcObj); } } if (targetType.isBean()) { if (srcType.isBean()) { return copy(srcObj, targetType.clazz()); } else if (srcType.isMap()) { return Maps.map2Bean((Map) srcObj, targetType.clazz()); } } else if (targetType.isMap()) { if (srcType.isBean() && targetType.getParameterTypes()[0].clazz().isAssignableFrom(String.class) && Object.class.equals(targetType.getParameterTypes()[1].clazz())) { try { final Map result = newMap((Class) targetType.clazz()); Maps.bean2Map(srcObj, result); return (T) result; } catch (final Exception e) { // ignore. } } else if (srcType.isMap()) { final Map srcMap = (Map) srcObj; final Optional firstNonNullKeyOp = firstNonNull(srcMap.keySet()); final Optional firstNonNullValueOp = firstNonNull(srcMap.values()); if ((firstNonNullKeyOp.isEmpty() || targetType.getParameterTypes()[0].clazz().isAssignableFrom(firstNonNullKeyOp.get().getClass())) && (firstNonNullValueOp.isEmpty() || targetType.getParameterTypes()[1].clazz().isAssignableFrom(firstNonNullValueOp.get().getClass()))) { final Map result = newMap((Class) targetType.clazz(), srcMap.size()); result.putAll(srcMap); return (T) result; } } } if (targetType.isCollection()) { if (srcType.isCollection()) { final Collection srcColl = (Collection) srcObj; final Optional op = firstNonNull(srcColl); if (op.isEmpty() || targetType.getParameterTypes()[0].clazz().isAssignableFrom(op.get().getClass())) { final Collection result = newCollection((Class) targetType.clazz(), srcColl.size()); result.addAll(srcColl); return (T) result; } } else if (srcType.isObjectArray() && targetType.getParameterTypes()[0].clazz().isAssignableFrom(srcType.clazz().getComponentType())) { final Object[] srcArray = (Object[]) srcObj; final Collection result = newCollection((Class) targetType.clazz(), srcArray.length); result.addAll(Arrays.asList(srcArray)); return (T) result; } else if (targetType.getElementType().clazz().isAssignableFrom(srcType.clazz())) { final Collection result = newCollection((Class) targetType.clazz(), 1); result.add(srcObj); return (T) result; } } if (targetType.isObjectArray()) { if (srcType.isCollection()) { final Collection srcColl = (Collection) srcObj; final Optional op = firstNonNull(srcColl); if (op.isEmpty() || targetType.clazz().getComponentType().isAssignableFrom(op.get().getClass())) { try { final Object[] result = newArray(targetType.clazz().getComponentType(), srcColl.size()); srcColl.toArray(result); return (T) result; } catch (final Exception e) { // ignore; } } } else if (targetType.getElementType().clazz().isAssignableFrom(srcType.clazz())) { final Object[] result = newArray(targetType.clazz().getComponentType(), 1); result[0] = srcObj; return (T) result; } // If it works, it has returned by: targetType.clazz().isAssignableFrom(srcClass) // } else if (srcType.isObjectArray()) { // try { // final Object[] srcArray = (Object[]) obj; // final Object[] result = newArray(targetType.clazz().getComponentType(), srcArray.length); // copy(srcArray, 0, result, 0, srcArray.length); // return (T) result; // } catch (Exception e) { // // ignore; // } // } } if (targetType.clazz().equals(byte[].class)) { if (srcType.clazz().equals(Blob.class)) { final Blob blob = (Blob) srcObj; try { return (T) blob.getBytes(1, (int) blob.length()); } catch (final SQLException e) { throw new UncheckedSQLException(e); } finally { try { blob.free(); } catch (final SQLException e) { throw new UncheckedSQLException(e); //NOSONAR } } } else if (srcType.clazz().equals(InputStream.class)) { final InputStream is = (InputStream) srcObj; try { return (T) IOUtil.readAllBytes(is); } finally { IOUtil.close(is); } } } else if (targetType.clazz().equals(char[].class)) { if (srcType.clazz().equals(Clob.class)) { final Clob clob = (Clob) srcObj; try { return (T) clob.getSubString(1, (int) clob.length()).toCharArray(); } catch (final SQLException e) { throw new UncheckedSQLException(e); } finally { try { clob.free(); } catch (final SQLException e) { throw new UncheckedSQLException(e); //NOSONAR } } } else if (srcType.clazz().equals(Reader.class)) { final Reader reader = (Reader) srcObj; try { return (T) IOUtil.readAllChars(reader); } finally { IOUtil.close(reader); } } else if (srcType.clazz().equals(InputStream.class)) { final InputStream is = (InputStream) srcObj; try { return (T) IOUtil.readAllChars(is); } finally { IOUtil.close(is); } } } else if (targetType.clazz().equals(String.class)) { if (CharSequence.class.isAssignableFrom(srcType.clazz())) { return (T) ((CharSequence) srcObj).toString(); } else if (srcType.clazz().equals(Clob.class)) { final Clob clob = (Clob) srcObj; try { return (T) clob.getSubString(1, (int) clob.length()); } catch (final SQLException e) { throw new UncheckedSQLException(e); } finally { try { clob.free(); } catch (final SQLException e) { throw new UncheckedSQLException(e); //NOSONAR } } } else if (srcType.clazz().equals(Reader.class)) { final Reader reader = (Reader) srcObj; try { return (T) IOUtil.readAllToString(reader); } finally { IOUtil.close(reader); } } else if (srcType.clazz().equals(InputStream.class)) { final InputStream is = (InputStream) srcObj; try { return (T) IOUtil.readAllToString(is); } finally { IOUtil.close(is); } } } else if (targetType.clazz().equals(InputStream.class) && srcType.clazz().equals(byte[].class)) { return (T) new ByteArrayInputStream((byte[]) srcObj); } else if (targetType.clazz().equals(Reader.class) && CharSequence.class.isAssignableFrom(srcType.clazz())) { return (T) new StringReader(srcObj.toString()); } if (srcObj instanceof final AutoCloseable closeable) { try { return targetType.valueOf(srcObj); } finally { IOUtil.closeQuietly(closeable); } } else { return targetType.valueOf(srcObj); } } /** * Casts the given object to the specified target type if possible. * If the object is {@code null} or cannot be assigned to the target type, an empty {@code Nullable} is returned. * Note that {@code null} can be assigned to any Object type except primitive types: boolean/char/byte/short/int/long/double. * * @param The type of the target object after casting. * @param val The object to be casted. * @param targetType The class of the target type to which the object is to be casted. * @return A {@code Nullable} containing the casted object if the casting is successful, or an empty {@code Nullable} if the object is {@code null} or cannot be casted to the target type. */ @SuppressWarnings("unchecked") @Beta public static Nullable castIfAssignable(final Object val, final Class targetType) { if (ClassUtil.isPrimitiveType(targetType)) { return val != null && ClassUtil.wrap(targetType).isAssignableFrom(val.getClass()) ? Nullable.of((T) val) : Nullable.empty(); } return val == null || targetType.isAssignableFrom(val.getClass()) ? Nullable.of((T) val) : Nullable.empty(); } /** * Casts the given object to the specified target type if possible using the provided Type instance. * If the object is {@code null} or cannot be assigned to the target type, an empty {@code Nullable} is returned. * Note that {@code null} can be assigned to any Object type except primitive types: boolean/char/byte/short/int/long/double. * * @param The type of the target object after casting. * @param val The object to be casted. * @param targetType The Type instance of the target type to which the object is to be casted. * @return A {@code Nullable} containing the casted object if the casting is successful, or an empty {@code Nullable} if the object is {@code null} or cannot be casted to the target type. */ @Beta public static Nullable castIfAssignable(final Object val, final Type targetType) { return castIfAssignable(val, targetType.clazz()); } // /** // * Checks if is bean. // * // * @param cls // * @return true, if is bean // * @see ClassUtil#isBeanClass(Class) // * @deprecated replaced by {@code ClassUtil.isBeanClass(Class)} // */ // @Deprecated // public static boolean isBeanClass(final Class cls) { // return ClassUtil.isBeanClass(cls); // } private static final Set> notKryoCompatible = newConcurrentHashSet(); /** * Retrieves the property names of the given bean class. * * @param beanClass the class of the bean whose property names are to be retrieved. * @return an ImmutableList of strings representing the property names of the given bean class. * @throws IllegalArgumentException if the specified bean class is {@code null}. * @see ClassUtil#getPropNameList(Class) */ public static ImmutableList getPropNames(final Class beanClass) { return ClassUtil.getPropNameList(beanClass); } /** * Retrieves the property names of the given bean class excluding the specified property names. * * @param beanClass the class of the bean whose property names are to be retrieved. * @param propNameToExclude a set of property names to be excluded from the returned list. * @return a List of strings representing the property names of the given bean class excluding the specified property names. * @throws IllegalArgumentException if the specified bean class is {@code null}. * @see ClassUtil#getPropNames(Class, Set) * @see ClassUtil#getPropNames(Class, Collection) */ public static List getPropNames(final Class beanClass, final Set propNameToExclude) { return ClassUtil.getPropNames(beanClass, propNameToExclude); } /** * Retrieves the property names of the given bean object. * * @param bean The bean object whose property names are to be retrieved. * @return A list of strings representing the property names of the given bean object. * @throws IllegalArgumentException if the specified bean object is {@code null}. * @see ClassUtil#getPropNameList(Class) * @see ClassUtil#getPropNames(Object, Predicate) * @see ClassUtil#getPropNames(Object, BiPredicate) */ public static List getPropNames(final Object bean) { checkArgNotNull(bean, cs.bean); return getPropNames(bean.getClass()); } static final BiPredicate NON_PROP_VALUE = (propName, propValue) -> propValue != null; /** * Retrieves the property names of the given bean object. * * @param bean The bean object whose property names are to be retrieved. * @param ignoreNullValue If {@code true}, the method will ignore property names with {@code null} values. * @return A list of strings representing the property names of the given bean object. If {@code ignoreNullValue} is {@code true}, properties with {@code null} values are not included in the list. * @throws IllegalArgumentException if the specified bean object is {@code null}. * @see ClassUtil#getPropNameList(Class) * @see ClassUtil#getPropNames(Object, Predicate) * @see ClassUtil#getPropNames(Object, BiPredicate) */ public static List getPropNames(final Object bean, final boolean ignoreNullValue) { if (ignoreNullValue) { return ClassUtil.getPropNames(bean, NON_PROP_VALUE); } else { return getPropNames(bean); } } /** * Retrieves the value of the specified property from the given bean object. * * @param The type of the property value. * @param bean The bean object from which the property value is to be retrieved. * @param propName The name of the property whose value is to be retrieved. * @return The value of the specified property of the given bean object. * @throws IllegalArgumentException if the specified bean object is {@code null}. * @see ClassUtil#getPropValue(Object, String) * @see BeanInfo#getPropValue(Object, String) */ public static T getPropValue(final Object bean, final String propName) { return ClassUtil.getPropValue(bean, propName); } /** * Retrieves the value of the specified property from the given bean object. * * @param The type of the property value. * @param bean The bean object from which the property value is to be retrieved. * @param propName The name of the property whose value is to be retrieved. * @param ignoreUnmatchedProperty If {@code true}, the method will not throw an exception if the property does not exist in the bean object. * @return The value of the specified property of the given bean object. * @throws IllegalArgumentException if the specified bean object is {@code null} or if the property does not exist and ignoreUnmatchedProperty is {@code false}. * @see ClassUtil#getPropValue(Object, String, boolean) * @see BeanInfo#getPropValue(Object, String) */ public static T getPropValue(final Object bean, final String propName, final boolean ignoreUnmatchedProperty) { return ClassUtil.getPropValue(bean, propName, ignoreUnmatchedProperty); } /** * Sets the value of the specified property in the given bean object. *
* Refer to setPropValue(Method, Object, Object). * * @param bean The bean object in which the property value is to be set. * @param propName The name of the property whose value is to be set. The property name is case-insensitive. * @param propValue The new value to be set for the specified property in the given bean object. * @throws IllegalArgumentException if the specified bean object is {@code null}. * @see ClassUtil#setPropValue(Object, String, Object) * @see BeanInfo#setPropValue(Object, String, Object) * @deprecated replaced by {@link BeanInfo#setPropValue(Object, String, Object)} */ @Deprecated public static void setPropValue(final Object bean, final String propName, final Object propValue) { ClassUtil.setPropValue(bean, propName, propValue, false); } /** * Clones the given object. * The object must be serializable and deserializable through {@code Kryo} or {@code JSON}. * * @param * @param obj a Java object which must be serializable and deserializable through {@code Kryo} or {@code JSON}. * @return {@code null} if {@code bean} is {@code null} */ @MayReturnNull @SuppressWarnings("unchecked") public static T clone(final T obj) { if (obj == null) { return null; // NOSONAR } return (T) clone(obj, obj.getClass()); } /** * Deeply copy by: obj -> serialize -> kryo/Json -> deserialize -> new object. * * @param * @param obj a Java object which must be serializable and deserializable through {@code Kryo} or {@code JSON}. * @param targetType * @return a new instance of {@code targetType} even if {@code bean} is {@code null}. * @throws IllegalArgumentException if {@code targetType} is {@code null}. */ @SuppressWarnings("unchecked") public static T clone(final Object obj, @NotNull final Class targetType) throws IllegalArgumentException { checkArgNotNull(targetType, cs.targetType); if (obj == null) { if (ClassUtil.isBeanClass(targetType)) { return copy(null, targetType); } else { return newInstance(targetType); } } final Class srcCls = obj.getClass(); Object copy = null; if (Utils.kryoParser != null && targetType.equals(obj.getClass()) && !notKryoCompatible.contains(srcCls)) { try { copy = Utils.kryoParser.clone(obj); } catch (final Exception e) { notKryoCompatible.add(srcCls); // ignore. } } if (copy == null) { final String xml = Utils.abacusXMLParser.serialize(obj, Utils.xscForClone); copy = Utils.abacusXMLParser.deserialize(xml, targetType); } return (T) copy; } /** * Returns a copy of the given source bean. * * @param the type of the source bean * @param sourceBean the source bean to copy * @return a new instance of the same class with the same properties copied from the source bean, or {@code null} if the source bean is {@code null} */ @MayReturnNull @SuppressWarnings("unchecked") public static T copy(final T sourceBean) { if (sourceBean == null) { return null; // NOSONAR } return copy(sourceBean, (Class) sourceBean.getClass()); } /** * Returns a copy of the given source bean with selected properties. * * @param the type of the source bean * @param sourceBean the source bean to copy * @param selectPropNames the collection of property names to be copied * @return a new instance of the same class with the selected properties copied from the source bean, or {@code null} if the source bean is {@code null} */ @MayReturnNull public static T copy(final T sourceBean, final Collection selectPropNames) { if (sourceBean == null) { return null; // NOSONAR } return copy(sourceBean, selectPropNames, (Class) sourceBean.getClass()); } /** * Returns a copy of the given source bean with properties filtered by the specified predicate. * * @param the type of the source bean * @param sourceBean the source bean to copy * @param propFilter the predicate to filter properties to be copied * @return a new instance of the same class with the filtered properties copied from the source bean, or {@code null} if the source bean is {@code null} * @see BiPredicates#alwaysTrue() * @see Fn#identity() * @see Fn#selectFirst() */ @MayReturnNull public static T copy(final T sourceBean, final BiPredicate propFilter) { if (sourceBean == null) { return null; // NOSONAR } return copy(sourceBean, propFilter, (Class) sourceBean.getClass()); } /** * Returns a new instance of specified {@code targetType} with properties copied from the given source bean. * * @param the type of the target bean * @param sourceBean the source bean to copy * @param targetType the class of the target type * @return a new instance of the target type, even if the source bean is {@code null} * @throws IllegalArgumentException if the specified {@code targetType} is {@code null} */ public static T copy(final Object sourceBean, final Class targetType) throws IllegalArgumentException { return copy(sourceBean, (Collection) null, targetType); } /** * Returns a new instance of specified {@code targetType} with properties copied from the given source bean with selected properties. * * @param the type of the target bean * @param sourceBean the source bean to copy * @param selectPropNames the collection of property names to be copied * @param targetType the class of the target type * @return a new instance of the target type, even if the source bean is {@code null} * @throws IllegalArgumentException if the specified {@code targetType} is {@code null} */ public static T copy(final Object sourceBean, final Collection selectPropNames, @NotNull final Class targetType) throws IllegalArgumentException { return copy(sourceBean, selectPropNames, Fn.identity(), targetType); } /** * Returns a new instance of specified {@code targetType} with properties copied from the given source bean with selected properties. * * @param the type of the target bean * @param sourceBean the source bean to copy * @param selectPropNames the collection of property names to be copied * @param propNameConverter A Function used to convert the property names from the source object to the target object. The function takes a property name from the source object and returns the corresponding property name in the target object. * @param targetType the class of the target type * @return a new instance of the target type, even if the source bean is {@code null} * @throws IllegalArgumentException if the specified {@code targetType} is {@code null} * @see BiPredicates#alwaysTrue() * @see Fn#identity() * @see Fn#selectFirst() */ @SuppressWarnings({ "unchecked" }) public static T copy(final Object sourceBean, final Collection selectPropNames, final Function propNameConverter, @NotNull final Class targetType) throws IllegalArgumentException { checkArgNotNull(targetType, cs.targetType); if (sourceBean != null) { final Class srcCls = sourceBean.getClass(); if (selectPropNames == null && Utils.kryoParser != null && targetType.equals(srcCls) && !notKryoCompatible.contains(srcCls)) { try { final T copy = (T) Utils.kryoParser.copy(sourceBean); if (copy != null) { return copy; } } catch (final Exception e) { notKryoCompatible.add(srcCls); // ignore } } } final BeanInfo targetBeanInfo = ParserUtil.getBeanInfo(targetType); Object result = targetBeanInfo.createBeanResult(); if (sourceBean != null) { merge(sourceBean, result, selectPropNames, propNameConverter, Fn.selectFirst(), targetBeanInfo); } result = targetBeanInfo.finishBeanResult(result); return (T) result; } /** * Returns a new instance of specified {@code targetType} with properties copied from the given source bean, filtered by the specified predicate. * * @param the type of the target bean * @param sourceBean the source bean to copy * @param propFilter A BiPredicate used to filter the properties to be copied. The predicate takes a property name and its value, and returns {@code true} if the property should be copied. * @param targetType the class of the target type * @return a new instance of the target type, even if the source bean is {@code null} * @throws IllegalArgumentException if {@code targetBean} is {@code null}. * @see BiPredicates#alwaysTrue() * @see Fn#identity() * @see Fn#selectFirst() */ public static T copy(final Object sourceBean, final BiPredicate propFilter, final Class targetType) throws IllegalArgumentException { return copy(sourceBean, propFilter, Fn.identity(), targetType); } /** * Returns a new instance of specified {@code targetType} with properties copied from the given source bean, filtered by the specified predicate. * * @param the type of the target bean * @param sourceBean the source bean to copy * @param propFilter A BiPredicate used to filter the properties to be copied. The predicate takes a property name and its value, and returns {@code true} if the property should be copied. * @param propNameConverter A Function used to convert the property names from the source object to the target object. The function takes a property name from the source object and returns the corresponding property name in the target object. * @param targetType the class of the target type * @return a new instance of the target type, even if the source bean is {@code null} * @throws IllegalArgumentException if {@code targetBean} is {@code null}. * @see BiPredicates#alwaysTrue() * @see Fn#identity() * @see Fn#selectFirst() */ public static T copy(final Object sourceBean, final BiPredicate propFilter, final Function propNameConverter, final Class targetType) throws IllegalArgumentException { checkArgNotNull(targetType, cs.targetType); if (sourceBean != null) { final Class srcCls = sourceBean.getClass(); if (propFilter == BiPredicates.alwaysTrue() && Utils.kryoParser != null && targetType.equals(srcCls) && !notKryoCompatible.contains(srcCls)) { try { final T copy = (T) Utils.kryoParser.copy(sourceBean); if (copy != null) { return copy; } } catch (final Exception e) { notKryoCompatible.add(srcCls); // ignore } } } final BeanInfo targetBeanInfo = ParserUtil.getBeanInfo(targetType); Object result = targetBeanInfo.createBeanResult(); if (sourceBean != null) { merge(sourceBean, result, propFilter, propNameConverter, Fn.selectFirst(), targetBeanInfo); } result = targetBeanInfo.finishBeanResult(result); return (T) result; } /** * Returns a new instance of specified {@code targetType} with properties copied from the given source bean, except the properties specified in the {@code ignoredPropNames} set. * * @param the type of the target bean * @param sourceBean the source bean to copy * @param ignoreUnmatchedProperty if {@code true}, unmatched properties will be ignored, otherwise an exception will be thrown if unmatched properties are found * @param ignoredPropNames the set of property names to be ignored during copying * @param targetType the class of the target type * @return a new instance of the target type, even if the source bean is {@code null} * @throws IllegalArgumentException if the specified {@code targetType} is {@code null} */ @SuppressWarnings({ "unchecked" }) public static T copy(final Object sourceBean, final boolean ignoreUnmatchedProperty, final Set ignoredPropNames, @NotNull final Class targetType) throws IllegalArgumentException { checkArgNotNull(targetType, cs.targetType); if (sourceBean != null) { final Class srcCls = sourceBean.getClass(); if (ignoredPropNames == null && Utils.kryoParser != null && targetType.equals(srcCls) && !notKryoCompatible.contains(srcCls)) { try { final T copy = (T) Utils.kryoParser.copy(sourceBean); if (copy != null) { return copy; } } catch (final Exception e) { notKryoCompatible.add(srcCls); // ignore } } } final BeanInfo targetBeanInfo = ParserUtil.getBeanInfo(targetType); Object result = targetBeanInfo.createBeanResult(); if (sourceBean != null) { merge(sourceBean, result, ignoreUnmatchedProperty, ignoredPropNames, targetBeanInfo); } result = targetBeanInfo.finishBeanResult(result); return (T) result; } private static T merge(final Object sourceBean, @NotNull final T targetBean, final boolean ignoreUnmatchedProperty, final Set ignoredPropNames, final BeanInfo targetBeanInfo) throws IllegalArgumentException { if (sourceBean == null) { return targetBean; } final BeanInfo srcBeanInfo = ParserUtil.getBeanInfo(sourceBean.getClass()); Object propValue = null; for (final PropInfo propInfo : srcBeanInfo.propInfoList) { if (ignoredPropNames == null || !ignoredPropNames.contains(propInfo.name)) { propValue = propInfo.getPropValue(sourceBean); if (notNullOrDefault(propValue)) { targetBeanInfo.setPropValue(targetBean, propInfo, propValue, ignoreUnmatchedProperty); } } } return targetBean; } /** * Merges the properties from the source object into the target object. * The source object's properties will overwrite the same properties in the target object. * * @param The type of the target object. * @param sourceBean The source object from which properties are to be copied. This object should allow access to properties using getter methods. * @param targetBean The target object into which properties are to be copied. This object should allow access to properties using setter methods. * @return The specified target object with the merged properties. * @throws IllegalArgumentException if {@code targetBean} is {@code null}. */ public static T merge(final Object sourceBean, final T targetBean) throws IllegalArgumentException { return merge(sourceBean, targetBean, (Collection) null); } /** * Merges the properties from the source object into the target object using the specified merge function. * The source object's properties will overwrite the same properties in the target object. * * @param The type of the target object. * @param sourceBean The source object from which properties are to be copied. This object should allow access to properties using getter methods. * @param targetBean The target object into which properties are to be copied. This object should allow access to properties using setter methods. * @param mergeFunc A BinaryOperator used to merge the property values from the source object and the target object. The operator takes two parameters: the source property value and the target property value, and returns the resolved value to be set in the target object. * @return The specified target object with the merged properties. * @throws IllegalArgumentException if {@code targetBean} is {@code null}. * @see BiPredicates#alwaysTrue() * @see Fn#identity() * @see Fn#selectFirst() */ public static T merge(final Object sourceBean, final T targetBean, final BinaryOperator mergeFunc) throws IllegalArgumentException { return merge(sourceBean, targetBean, BiPredicates.alwaysTrue(), mergeFunc); } /** * Merges the properties from the source object into the target object using the specified merge function. * The source object's properties will overwrite the same properties in the target object. * * @param The type of the target object. * @param sourceBean The source object from which properties are to be copied. This object should allow access to properties using getter methods. * @param targetBean The target object into which properties are to be copied. This object should allow access to properties using setter methods. * @param propNameConverter A Function used to convert the property names from the source object to the target object. The function takes a property name from the source object and returns the corresponding property name in the target object. * @param mergeFunc A BinaryOperator used to merge the property values from the source object and the target object. The operator takes two parameters: the source property value and the target property value, and returns the resolved value to be set in the target object. * @return The specified target object with the merged properties. * @throws IllegalArgumentException if {@code targetBean} is {@code null}. * @see BiPredicates#alwaysTrue() * @see Fn#identity() * @see Fn#selectFirst() */ public static T merge(final Object sourceBean, final T targetBean, final Function propNameConverter, final BinaryOperator mergeFunc) throws IllegalArgumentException { return merge(sourceBean, targetBean, (Collection) null, propNameConverter, mergeFunc); } /** * Merges the selected properties from the source object into the target object. * The source object's properties will overwrite the same properties in the target object. * * @param The type of the target object. * @param sourceBean The source object from which properties are to be copied. This object should allow access to properties using getter methods. * @param targetBean The target object into which properties are to be copied. This object should allow access to properties using setter methods. * @param selectPropNames The collection of property names to be merged. * @return The specified target object with the merged properties. * @throws IllegalArgumentException if {@code targetBean} is {@code null}. */ public static T merge(final Object sourceBean, @NotNull final T targetBean, final Collection selectPropNames) throws IllegalArgumentException { return merge(sourceBean, targetBean, selectPropNames, Fn.identity()); } /** * Merges the selected properties from the source object into the target object using the specified merge function. * The source object's properties will overwrite the same properties in the target object. * * @param The type of the target object. * @param sourceBean The source object from which properties are to be copied. This object should allow access to properties using getter methods. * @param targetBean The target object into which properties are to be copied. This object should allow access to properties using setter methods. * @param selectPropNames The collection of property names to be merged. * @param mergeFunc A BinaryOperator used to merge the property values from the source object and the target object. The operator takes two parameters: the source property value and the target property value, and returns the resolved value to be set in the target object. * @return The specified target object with the merged properties. * @throws IllegalArgumentException if {@code targetBean} is {@code null}. * @see BiPredicates#alwaysTrue() * @see Fn#identity() * @see Fn#selectFirst() */ public static T merge(final Object sourceBean, @NotNull final T targetBean, final Collection selectPropNames, final BinaryOperator mergeFunc) throws IllegalArgumentException { return merge(sourceBean, targetBean, selectPropNames, Fn.identity(), mergeFunc); } /** * Merges the selected properties from the source object into the target object. * The source object's properties will overwrite the same properties in the target object. * * @param The type of the target object. * @param sourceBean The source object from which properties are to be copied. This object should allow access to properties using getter methods. * @param targetBean The target object into which properties are to be copied. This object should allow access to properties using setter methods. * @param selectPropNames The collection of property names to be merged. * @param propNameConverter A Function used to convert the property names from the source object to the target object. The function takes a property name from the source object and returns the corresponding property name in the target object. * @return The specified target object with the merged properties. * @throws IllegalArgumentException if {@code targetBean} is {@code null}. * @see BiPredicates#alwaysTrue() * @see Fn#identity() * @see Fn#selectFirst() */ public static T merge(final Object sourceBean, @NotNull final T targetBean, final Collection selectPropNames, final Function propNameConverter) throws IllegalArgumentException { checkArgNotNull(targetBean, cs.targetBean); return merge(sourceBean, targetBean, selectPropNames, propNameConverter, Fn.selectFirst(), ParserUtil.getBeanInfo(targetBean.getClass())); } /** * Merges the selected properties from the source object into the target object using the specified merge function. * The source object's properties will overwrite the same properties in the target object. * * @param The type of the target object. * @param sourceBean The source object from which properties are to be copied. This object should allow access to properties using getter methods. * @param targetBean The target object into which properties are to be copied. This object should allow access to properties using setter methods. * @param selectPropNames The collection of property names to be merged. * @param propNameConverter A Function used to convert the property names from the source object to the target object. The function takes a property name from the source object and returns the corresponding property name in the target object. * @param mergeFunc A BinaryOperator used to merge the property values from the source object and the target object. The operator takes two parameters: the source property value and the target property value, and returns the resolved value to be set in the target object. * @return The specified target object with the merged properties. * @throws IllegalArgumentException if {@code targetBean} is {@code null}. * @see BiPredicates#alwaysTrue() * @see Fn#identity() * @see Fn#selectFirst() */ public static T merge(final Object sourceBean, @NotNull final T targetBean, final Collection selectPropNames, final Function propNameConverter, final BinaryOperator mergeFunc) throws IllegalArgumentException { checkArgNotNull(targetBean, cs.targetBean); final BeanInfo targetBeanInfo = ParserUtil.getBeanInfo(targetBean.getClass()); return merge(sourceBean, targetBean, selectPropNames, propNameConverter, mergeFunc, targetBeanInfo); } private static T merge(final Object sourceBean, final T targetBean, final Collection selectPropNames, final Function propNameConverter, final BinaryOperator mergeFunc, final BeanInfo targetBeanInfo) { if (sourceBean == null) { return targetBean; } final boolean isIdentityPropNameConverter = propNameConverter == Fn. identity(); final BeanInfo srcBeanInfo = ParserUtil.getBeanInfo(sourceBean.getClass()); final BinaryOperator objMergeFunc = (BinaryOperator) mergeFunc; final boolean ignoreUnmatchedProperty = selectPropNames == null; Object propValue = null; String targetPropName = null; PropInfo targetPropInfo = null; if (selectPropNames == null) { for (final PropInfo propInfo : srcBeanInfo.propInfoList) { if (isIdentityPropNameConverter) { targetPropInfo = targetBeanInfo.getPropInfo(propInfo); } else { targetPropName = propNameConverter.apply(propInfo.name); if (propInfo.name.equals(targetPropName)) { targetPropInfo = targetBeanInfo.getPropInfo(propInfo); } else { targetPropInfo = targetBeanInfo.getPropInfo(targetPropName); } } if (targetPropInfo == null) { // if (!ignoreUnmatchedProperty) { // throw new IllegalArgumentException( // "No property found by name: " + propInfo.name + " in target bean class: " + targetBean.getClass()); // } } else { propValue = propInfo.getPropValue(sourceBean); targetPropInfo.setPropValue(targetBean, objMergeFunc.apply(propValue, targetPropInfo.getPropValue(targetBean))); } } } else { PropInfo propInfo = null; for (final String propName : selectPropNames) { propInfo = srcBeanInfo.getPropInfo(propName); if (isIdentityPropNameConverter) { targetPropInfo = targetBeanInfo.getPropInfo(propInfo); } else { targetPropName = propNameConverter.apply(propInfo.name); if (propInfo.name.equals(targetPropName)) { targetPropInfo = targetBeanInfo.getPropInfo(propInfo); } else { targetPropInfo = targetBeanInfo.getPropInfo(targetPropName); } } if (targetPropInfo == null) { //noinspection ConstantValue if (!ignoreUnmatchedProperty) { //NOSONAR throw new IllegalArgumentException("No property found by name: " + propName + " in target bean class: " + targetBean.getClass()); //NOSONAR } } else { propValue = srcBeanInfo.getPropValue(sourceBean, propName); targetPropInfo.setPropValue(targetBean, objMergeFunc.apply(propValue, targetPropInfo.getPropValue(targetBean))); } } } return targetBean; } /** * Merges the filtered properties from the source object into the target object, * The source object's properties will overwrite the same properties in the target object. * * @param The type of the target object. * @param sourceBean The source object from which properties are to be copied. This object should allow access to properties using getter methods. * @param targetBean The target object into which properties are to be copied. This object should allow access to properties using setter methods. * @param propFilter A BiPredicate used to filter the properties to be merged. The predicate takes a property name and its value, and returns {@code true} if the property should be merged. * @return The specified target object with the merged properties. * @throws IllegalArgumentException if {@code targetBean} is {@code null}. * @see BiPredicates#alwaysTrue() * @see Fn#identity() * @see Fn#selectFirst() */ public static T merge(final Object sourceBean, final T targetBean, final BiPredicate propFilter) throws IllegalArgumentException { return merge(sourceBean, targetBean, propFilter, Fn.selectFirst()); } /** * Merges the filtered properties from the source object into the target object using the specified merge function. * The source object's properties will overwrite the same properties in the target object. * * @param The type of the target object after merging. * @param sourceBean The source object whose properties are to be merged. This object should allow access to properties using getter methods. * @param targetBean The target object to which the properties are to be merged. This object should allow access to properties using setter methods. * @param propFilter A BiPredicate used to filter the properties to be merged. The predicate takes a property name and its value, and returns {@code true} if the property should be merged. * @param mergeFunc A BinaryOperator used to merge the property values from the source object and the target object. The operator takes two parameters: the source property value and the target property value, and returns the resolved value to be set in the target object. * @return The specified target object with the merged properties. * @throws IllegalArgumentException if targetBean is {@code null}. * @see BiPredicates#alwaysTrue() * @see Fn#identity() * @see Fn#selectFirst() */ public static T merge(final Object sourceBean, @NotNull final T targetBean, final BiPredicate propFilter, final BinaryOperator mergeFunc) throws IllegalArgumentException { return merge(sourceBean, targetBean, propFilter, Fn.identity(), mergeFunc); } /** * Merges the filtered properties from the source object into the target object using the specified merge function. * The source object's properties will overwrite the same properties in the target object. * * @param The type of the target object after merging. * @param sourceBean The source object whose properties are to be merged. This object should allow access to properties using getter methods. * @param targetBean The target object to which the properties are to be merged. This object should allow access to properties using setter methods. * @param propFilter A BiPredicate used to filter the properties to be merged. The predicate takes a property name and its value, and returns {@code true} if the property should be merged. * @param propNameConverter A Function used to convert the property names from the source object to the target object. The function takes a property name from the source object and returns the corresponding property name in the target object. * @return The specified target object with the merged properties. * @throws IllegalArgumentException if targetBean is {@code null}. * @see BiPredicates#alwaysTrue() * @see Fn#identity() * @see Fn#selectFirst() */ public static T merge(final Object sourceBean, @NotNull final T targetBean, final BiPredicate propFilter, final Function propNameConverter) throws IllegalArgumentException { return merge(sourceBean, targetBean, propFilter, propNameConverter, Fn.selectFirst()); } /** * Merges the filtered properties from the source object into the target object using the specified merge function. * The source object's properties will overwrite the same properties in the target object. * * @param The type of the target object after merging. * @param sourceBean The source object whose properties are to be merged. This object should allow access to properties using getter methods. * @param targetBean The target object to which the properties are to be merged. This object should allow access to properties using setter methods. * @param propFilter A BiPredicate used to filter the properties to be merged. The predicate takes a property name and its value, and returns {@code true} if the property should be merged. * @param propNameConverter A Function used to convert the property names from the source object to the target object. The function takes a property name from the source object and returns the corresponding property name in the target object. * @param mergeFunc A BinaryOperator used to merge the property values from the source object and the target object. The operator takes two parameters: the source property value and the target property value, and returns the resolved value to be set in the target object. * @return The specified target object with the merged properties. * @throws IllegalArgumentException if targetBean is {@code null}. * @see BiPredicates#alwaysTrue() * @see Fn#identity() * @see Fn#selectFirst() */ public static T merge(final Object sourceBean, @NotNull final T targetBean, final BiPredicate propFilter, final Function propNameConverter, final BinaryOperator mergeFunc) throws IllegalArgumentException { checkArgNotNull(targetBean, cs.targetBean); final BeanInfo targetBeanInfo = ParserUtil.getBeanInfo(targetBean.getClass()); return merge(sourceBean, targetBean, propFilter, propNameConverter, mergeFunc, targetBeanInfo); } private static T merge(final Object sourceBean, final T targetBean, final BiPredicate propFilter, final Function propNameConverter, final BinaryOperator mergeFunc, final BeanInfo targetBeanInfo) { if (sourceBean == null) { return targetBean; } final boolean isIdentityPropNameConverter = propNameConverter == Fn. identity(); final BeanInfo srcBeanInfo = ParserUtil.getBeanInfo(sourceBean.getClass()); final BiPredicate objPropFilter = (BiPredicate) propFilter; final BinaryOperator objPropMergeFunc = (BinaryOperator) mergeFunc; Object propValue = null; PropInfo targetPropInfo = null; String targetPropName = null; for (final PropInfo propInfo : srcBeanInfo.propInfoList) { propValue = propInfo.getPropValue(sourceBean); if (objPropFilter.test(propInfo.name, propValue)) { if (isIdentityPropNameConverter) { targetPropInfo = targetBeanInfo.getPropInfo(propInfo); } else { targetPropName = propNameConverter.apply(propInfo.name); if (propInfo.name.equals(targetPropName)) { targetPropInfo = targetBeanInfo.getPropInfo(propInfo); } else { targetPropInfo = targetBeanInfo.getPropInfo(targetPropName); } } if (targetPropInfo == null) { throw new IllegalArgumentException("No property found by name: " + propInfo.name + " in target bean class: " + targetBean.getClass()); } targetPropInfo.setPropValue(targetBean, objPropMergeFunc.apply(propValue, targetPropInfo.getPropValue(targetBean))); } } return targetBean; } /** * Merges the properties from the source object into the target object, except the properties specified in the {@code ignoredPropNames} set. * The source object's properties will overwrite the same properties in the target object. * * @param The type of the target object. * @param sourceBean The source object from which properties are to be copied. This object should allow access to properties using getter methods. * @param targetBean The target object into which properties are to be copied. This object should allow access to properties using setter methods. * @param ignoreUnmatchedProperty if {@code true}, unmatched properties will be ignored, otherwise an exception will be thrown if unmatched properties are found * @param ignoredPropNames The set of property names to be ignored during merging. * @return The specified target object with the merged properties. * @throws IllegalArgumentException if {@code targetBean} is {@code null}. */ public static T merge(final Object sourceBean, @NotNull final T targetBean, final boolean ignoreUnmatchedProperty, final Set ignoredPropNames) throws IllegalArgumentException { checkArgNotNull(targetBean, cs.targetBean); if (sourceBean == null) { return targetBean; } return merge(sourceBean, targetBean, ignoreUnmatchedProperty, ignoredPropNames, ParserUtil.getBeanInfo(targetBean.getClass())); } /** * Merges the properties from the source object into the target object using the specified merge function, except the properties specified in the {@code ignoredPropNames} set. * The source object's properties will overwrite the same properties in the target object. * * @param The type of the target object. * @param sourceBean The source object from which properties are to be copied. This object should allow access to properties using getter methods. * @param targetBean The target object into which properties are to be copied. This object should allow access to properties using setter methods. * @param ignoreUnmatchedProperty if {@code true}, unmatched properties will be ignored, otherwise an exception will be thrown if unmatched properties are found * @param ignoredPropNames The set of property names to be ignored during merging. * @param mergeFunc A BinaryOperator used to merge the property values from the source object and the target object. The operator takes two parameters: the source property value and the target property value, and returns the resolved value to be set in the target object. * @return The specified target object with the merged properties. * @throws IllegalArgumentException if {@code targetBean} is {@code null}. */ public static T merge(final Object sourceBean, @NotNull final T targetBean, final boolean ignoreUnmatchedProperty, final Set ignoredPropNames, final BinaryOperator mergeFunc) throws IllegalArgumentException { checkArgNotNull(targetBean, cs.targetBean); if (sourceBean == null) { return targetBean; } final BeanInfo srcBeanInfo = ParserUtil.getBeanInfo(sourceBean.getClass()); final BeanInfo targetBeanInfo = ParserUtil.getBeanInfo(targetBean.getClass()); final BinaryOperator objMergeFunc = (BinaryOperator) mergeFunc; PropInfo targetPropInfo = null; Object propValue = null; for (final PropInfo propInfo : srcBeanInfo.propInfoList) { if (ignoredPropNames == null || !ignoredPropNames.contains(propInfo.name)) { targetPropInfo = targetBeanInfo.getPropInfo(propInfo); if (targetPropInfo == null) { if (!ignoreUnmatchedProperty) { throw new IllegalArgumentException("No property found by name: " + propInfo.name + " in target bean class: " + targetBean.getClass()); } } else { propValue = propInfo.getPropValue(sourceBean); targetPropInfo.setPropValue(targetBean, objMergeFunc.apply(propValue, targetPropInfo.getPropValue(targetBean))); } } } return targetBean; } /** * Erases the properties of the given bean object. * * This method sets the properties specified by the property names to their default values. * The default value is determined by the type of the property. For example, primitive numeric properties are set to 0, primitive boolean properties are set to {@code false}, and object properties are set to {@code null}. * * @param bean The bean object whose properties are to be erased. If this is {@code null}, the method does nothing. * @param propNames The names of the properties to be erased. These should correspond to the getter/setter methods in the bean object. If this is empty, the method does nothing. */ public static void erase(final Object bean, final String... propNames) { if (bean == null || isEmpty(propNames)) { return; } final BeanInfo beanInfo = ParserUtil.getBeanInfo(bean.getClass()); for (final String propName : propNames) { beanInfo.setPropValue(bean, propName, null); } } /** * Erases the properties of the given bean object. * * This method sets the properties specified by the property names to their default values. * The default value is determined by the type of the property. For example, primitive numeric properties are set to 0, primitive boolean properties are set to {@code false}, and object properties are set to {@code null}. * * @param bean The bean object whose properties are to be erased. If this is {@code null}, the method does nothing. * @param propNames The names of the properties to be erased. These should correspond to the getter/setter methods in the bean object. If this is empty, the method does nothing. */ public static void erase(final Object bean, final Collection propNames) { if (bean == null || isEmpty(propNames)) { return; } final BeanInfo beanInfo = ParserUtil.getBeanInfo(bean.getClass()); for (final String propName : propNames) { beanInfo.setPropValue(bean, propName, null); } } /** * Erases all the properties of the given bean object. * * This method sets all properties of the bean object to their default values. * The default value is determined by the type of the property. For example, primitive numeric properties are set to 0, primitive boolean properties are set to {@code false}, and object properties are set to {@code null}. * * @param bean The bean object whose properties are to be erased. If this is {@code null}, the method does nothing. */ public static void eraseAll(final Object bean) { if (bean == null) { return; } final Class cls = bean.getClass(); final BeanInfo beanInfo = ParserUtil.getBeanInfo(cls); for (final PropInfo propInfo : beanInfo.propInfoList) { propInfo.setPropValue(bean, null); } } /** * Returns an immutable/unmodifiable list of all the enum constants in the specified enum class. * * This method retrieves all the enum constants defined in the given enum class and returns them as an ImmutableList. * The order of the constants in the list is the order in which they're declared in the enum class. * * @param The type of the enum constants. This should be an enum type. * @param enumClass The class object of the enum type whose constants are to be listed. Must not be {@code null}. * @return An ImmutableList containing all the enum constants in the order they're declared in the enum class. */ public static > ImmutableList enumListOf(final Class enumClass) { checkArgNotNull(enumClass, cs.enumClass); ImmutableList enumList = (ImmutableList) enumListPool.get(enumClass); if (enumList == null) { enumList = ImmutableList.wrap(asList(enumClass.getEnumConstants())); enumListPool.put(enumClass, enumList); } return enumList; } /** * Returns an immutable/unmodifiable set of all the enum constants in the specified enum class. * * This method retrieves all the enum constants defined in the given enum class and returns them as an ImmutableSet. * The order of the constants in the set is the order in which they're declared in the enum class. * * @param The type of the enum constants. This should be an enum type. * @param enumClass The class object of the enum type whose constants are to be listed. Must not be {@code null}. * @return An ImmutableSet containing all the enum constants in the order they're declared in the enum class. */ public static > ImmutableSet enumSetOf(final Class enumClass) { checkArgNotNull(enumClass, cs.enumClass); ImmutableSet enumSet = (ImmutableSet) enumSetPool.get(enumClass); if (enumSet == null) { enumSet = ImmutableSet.wrap(EnumSet.allOf(enumClass)); enumSetPool.put(enumClass, enumSet); } return enumSet; } /** * Returns an immutable/unmodifiable bi-directional map of all the enum constants in the specified enum class to their names. * * This method retrieves all the enum constants defined in the given enum class and maps them to their names as an ImmutableBiMap. * The order of the constants in the map is the order in which they're declared in the enum class. * * @param The type of the enum constants. This should be an enum type. * @param enumClass The class object of the enum type whose constants are to be listed. Must not be {@code null}. * @return An ImmutableBiMap where each key-value pair corresponds to an enum constant and its name. */ public static > ImmutableBiMap enumMapOf(final Class enumClass) { checkArgNotNull(enumClass, cs.enumClass); ImmutableBiMap enumMap = (ImmutableBiMap) enumMapPool.get(enumClass); if (enumMap == null) { final EnumMap keyMap = new EnumMap<>(enumClass); final Map valueMap = new HashMap<>(); for (final E e : enumClass.getEnumConstants()) { keyMap.put(e, e.name()); valueMap.put(e.name(), e); } enumMap = ImmutableBiMap.wrap(new BiMap<>(keyMap, valueMap)); enumMapPool.put(enumClass, enumMap); } return enumMap; } /** * Invokes the specified constructor with the provided arguments to create new instances of a class. * * @param The type of the object to be created. * @param c The Constructor object representing the constructor to be invoked. Must not be {@code null}. * @param args The array of arguments to be passed to the constructor. It can be empty if the constructor takes no arguments. * @return A new instance of the class that the constructor belongs to. * @throws InstantiationException If the class that declares the underlying constructor represents an abstract class. * @throws IllegalAccessException If this Constructor object enforces Java language access control and the underlying constructor is inaccessible. * @throws IllegalArgumentException If the number of actual and formal parameters differ, or if an unwrapping conversion for primitive arguments fails. * @throws InvocationTargetException If the underlying constructor throws an exception. */ @SuppressWarnings({ "deprecation" }) static T invoke(final Constructor c, final Object... args) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { if (!c.isAccessible()) { ClassUtil.setAccessibleQuietly(c, true); } return c.newInstance(args); } /** * Creates a new proxy instance for the specified interface using the provided invocation handler. * * This method is a utility for creating dynamic proxies. A dynamic proxy class is a class that implements a list of interfaces specified at runtime such that a method invocation through one of the interfaces on an instance of the class will be encoded and dispatched to another object through a uniform interface. * Thus, a dynamic proxy class can be used to create an object that can implement an arbitrary set of interfaces specified at runtime. * * @param The type of the interface for the proxy class to implement. * @param interfaceClass The Class object of the interface for the proxy class to implement. Must not be {@code null}. * @param h The invocation handler to dispatch method invocations to. It's an object that implements the InvocationHandler interface. * @return a proxy instance that implements the specified interface(s) and dispatches method invocations to the specified invocation handler. * @see java.lang.reflect.Proxy#newProxyInstance(ClassLoader, Class[], InvocationHandler) */ public static T newProxyInstance(final Class interfaceClass, final InvocationHandler h) { return newProxyInstance(asArray(interfaceClass), h); } /** * Creates a new proxy instance for the specified interfaces using the provided invocation handler. * * This method is a utility for creating dynamic proxies. A dynamic proxy class is a class that implements a list of interfaces specified at runtime such that a method invocation through one of the interfaces on an instance of the class will be encoded and dispatched to another object through a uniform interface. * Thus, a dynamic proxy class can be used to create an object that can implement an arbitrary set of interfaces specified at runtime. * * @param The type of the interface for the proxy class to implement. * @param interfaceClasses The array of Class objects of the interfaces for the proxy class to implement. Must not be {@code null}. * @param h The invocation handler to dispatch method invocations to. It's an object that implements the InvocationHandler interface. * @return a proxy instance that implements the specified interface(s) and dispatches method invocations to the specified invocation handler. * @see java.lang.reflect.Proxy#newProxyInstance(ClassLoader, Class[], InvocationHandler) */ public static T newProxyInstance(final Class[] interfaceClasses, final InvocationHandler h) { return (T) Proxy.newProxyInstance(CommonUtil.class.getClassLoader(), interfaceClasses, h); // NOSONAR } /** * Creates a new instance of the specified class. * * @param the type of the object to be created * @param cls the class of the object to be created * @return a new instance of the specified class * @throws IllegalArgumentException if the class is abstract or cannot be instantiated * @see Suppliers#ofCollection(Class) * @see Suppliers#registerForCollection(Class, java.util.function.Supplier) * @see Suppliers#ofMap(Class) * @see Suppliers#registerForMap(Class, java.util.function.Supplier) * @see IntFunctions#ofCollection(Class) * @see IntFunctions#registerForCollection(Class, java.util.function.IntFunction) * @see IntFunctions#ofMap(Class) * @see IntFunctions#registerForMap(Class, java.util.function.IntFunction) */ @SuppressWarnings("rawtypes") public static T newInstance(final Class cls) { if (Modifier.isAbstract(cls.getModifiers())) { if (Collection.class.isAssignableFrom(cls)) { return (T) Suppliers.ofCollection((Class) cls).get(); } else if (Map.class.isAssignableFrom(cls)) { return (T) Suppliers.ofMap((Class) cls).get(); } else { throw new IllegalArgumentException("Can't create instance for abstract class: " + cls); } } if (!Modifier.isStatic(cls.getModifiers()) && ClassUtil.isAnonymousOrMemberClass(cls)) { try { // http://stackoverflow.com/questions/2097982/is-it-possible-to-create-an-instance-of-nested-class-using-java-reflection final List> toInstantiate = new ArrayList<>(); Class parent = cls.getEnclosingClass(); do { toInstantiate.add(parent); parent = parent.getEnclosingClass(); } while (parent != null && !Modifier.isStatic(parent.getModifiers()) && ClassUtil.isAnonymousOrMemberClass(parent)); if (parent != null) { toInstantiate.add(parent); } reverse(toInstantiate); Object instance = null; for (final Class current : toInstantiate) { instance = instance == null ? invoke(ClassUtil.getDeclaredConstructor(current)) : invoke(ClassUtil.getDeclaredConstructor(current, instance.getClass()), instance); } //noinspection DataFlowIssue return invoke(ClassUtil.getDeclaredConstructor(cls, instance.getClass()), instance); } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { throw ExceptionUtil.toRuntimeException(e, true); } } else { try { final Constructor constructor = ClassUtil.getDeclaredConstructor(cls); if (constructor == null) { throw new IllegalArgumentException("No default constructor found in class: " + ClassUtil.getCanonicalClassName(cls)); } return invoke(constructor); } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { throw ExceptionUtil.toRuntimeException(e, true); } } } /** * Creates a new instance of the specified bean class. * * @param the type of the object to be created * @param targetType the class of the object to be created * @return a new instance of the specified class * @throws IllegalArgumentException if the class is abstract or cannot be instantiated */ public static T newBean(final Class targetType) { return newInstance(targetType); } /** * Creates a new collection of the specified type. * * @param the type of elements in the collection * @param targetType the class of the collection to be created * @return a new collection of the specified type * @see Suppliers#ofCollection(Class) * @see Suppliers#registerForCollection(Class, java.util.function.Supplier) */ @SuppressWarnings("rawtypes") public static Collection newCollection(final Class targetType) { return Suppliers. ofCollection(targetType).get(); } /** * Creates a new collection of the specified type with the given initial size. * * @param the type of elements in the collection * @param targetType the class of the collection to be created * @param size the initial size of the collection * @return a new collection of the specified type with the given initial size * @see IntFunctions#ofCollection(Class) * @see IntFunctions#registerForCollection(Class, java.util.function.IntFunction) */ @SuppressWarnings("rawtypes") public static Collection newCollection(final Class targetType, final int size) { return IntFunctions. ofCollection(targetType).apply(size); } /** * Creates a new map of the specified type. * * @param the type of keys maintained by the map * @param the type of mapped values * @param targetType the class of the map to be created * @return a new map of the specified type * @see Suppliers#ofMap(Class) * @see Suppliers#registerForMap(Class, java.util.function.Supplier) */ @SuppressWarnings("rawtypes") public static Map newMap(final Class targetType) { return Suppliers. ofMap(targetType).get(); } /** * Creates a new map of the specified type with the given initial size. * * @param the type of keys maintained by the map * @param the type of mapped values * @param targetType the class of the map to be created * @param size the initial size of the map * @return a new map of the specified type with the given initial size * @see IntFunctions#ofMap(Class) * @see IntFunctions#registerForMap(Class, java.util.function.IntFunction) */ @SuppressWarnings("rawtypes") public static Map newMap(final Class targetType, final int size) { return IntFunctions. ofMap(targetType).apply(size); } /** * Creates a new array of the specified component type and length. * * @param the type of the array elements * @param componentType the class of the component type of the array * @param length the length of the new array * @return a new array of the specified component type and length * @throws NegativeArraySizeException if the specified length is negative * @see java.lang.reflect.Array#newInstance(Class, int) */ public static T newArray(final Class componentType, final int length) { return Array.newInstance(componentType, length); } /** * Creates a new array of the specified component type and dimensions. * * @param the type of the array elements * @param componentType the class of the component type of the array * @param dimensions the dimensions of the new array * @return a new array of the specified component type and dimensions * @throws IllegalArgumentException if the specified component type is {@code null} or if the dimensions are invalid * @throws NegativeArraySizeException if any of the specified dimensions are negative * @see java.lang.reflect.Array#newInstance(Class, int...) */ public static T newArray(final Class componentType, final int... dimensions) throws IllegalArgumentException, NegativeArraySizeException { return Array.newInstance(componentType, dimensions); } /** * * @param size * @return * @deprecated for internal use only */ @Deprecated @Internal @Beta static int initHashCapacity(final int size) { checkArgNotNegative(size, cs.size); if (size == 0) { return 0; } final int res = size < MAX_HASH_LENGTH ? (int) (size * 1.25) + 1 : MAX_ARRAY_SIZE; return res >= 1024 ? res : (Math.min(res, 256)); } /** * Creates a new instance of an ArrayList. * * @param the type of elements in the list * @return a new instance of an ArrayList */ public static ArrayList newArrayList() { //NOSONAR return new ArrayList<>(); } /** * Creates a new instance of an ArrayList with the specified initial capacity. * * @param the type of elements in the list * @param initialCapacity the initial capacity of the list * @return a new instance of an ArrayList with the specified initial capacity * @see java.util.ArrayList#ArrayList(int) */ public static ArrayList newArrayList(final int initialCapacity) { //NOSONAR return new ArrayList<>(initialCapacity); } /** * Creates a new instance of an ArrayList with the elements from the specified collection. * * @param the type of elements in the list * @param c the collection whose elements are to be placed into this list * @return a new instance of an ArrayList containing the elements from the specified collection * @see java.util.ArrayList#ArrayList(Collection) */ public static ArrayList newArrayList(final Collection c) { //NOSONAR return isEmpty(c) ? new ArrayList<>() : new ArrayList<>(c); } /** * Creates a new instance of a LinkedList. * * @param the type of elements in the list * @return a new instance of a LinkedList */ public static LinkedList newLinkedList() { //NOSONAR return new LinkedList<>(); } /** * Creates a new instance of a LinkedList with the elements from the specified collection. * * @param the type of elements in the list * @param c the collection whose elements are to be placed into this list * @return a new instance of a LinkedList containing the elements from the specified collection * @see java.util.LinkedList#LinkedList(Collection) */ public static LinkedList newLinkedList(final Collection c) { //NOSONAR return isEmpty(c) ? new LinkedList<>() : new LinkedList<>(c); } /** * Creates a new instance of a HashSet. * * @param the type of elements in the set * @return a new instance of a HashSet */ public static Set newHashSet() { return new HashSet<>(); } /** * Creates a new instance of a HashSet with the specified initial capacity. * * @param the type of elements in the set * @param initialCapacity the initial capacity of the set * @return a new instance of a HashSet with the specified initial capacity * @see java.util.HashSet#HashSet(int) */ public static Set newHashSet(final int initialCapacity) { return new HashSet<>(initHashCapacity(initialCapacity)); } /** * Creates a new instance of a HashSet with the elements from the specified collection. * * @param the type of elements in the set * @param c the collection whose elements are to be placed into this set * @return a new instance of a HashSet containing the elements from the specified collection * @see java.util.HashSet#HashSet(Collection) */ public static Set newHashSet(final Collection c) { return isEmpty(c) ? new HashSet<>() : new HashSet<>(c); } /** * Creates a new instance of HashSet. * * @param the type of elements in the set * @return a new instance of a HashSet */ public static Set newLinkedHashSet() { return new LinkedHashSet<>(); } /** * Creates a new instance of a LinkedHashSet with the specified initial capacity. * * @param the type of elements in the set * @param initialCapacity the initial capacity of the set * @return a new instance of a LinkedHashSet with the specified initial capacity * @see java.util.LinkedHashSet#LinkedHashSet(int) */ public static Set newLinkedHashSet(final int initialCapacity) { return new LinkedHashSet<>(initHashCapacity(initialCapacity)); } /** * Creates a new instance of a LinkedHashSet with the elements from the specified collection. * * @param the type of elements in the set * @param c the collection whose elements are to be placed into this set * @return a new instance of a LinkedHashSet containing the elements from the specified collection * @see java.util.LinkedHashSet#LinkedHashSet(Collection) */ public static Set newLinkedHashSet(final Collection c) { return isEmpty(c) ? new LinkedHashSet<>() : new LinkedHashSet<>(c); } /** * Creates a new instance of TreeSet. * * @param the type of elements in the set * @return a new instance of a TreeSet */ public static > TreeSet newTreeSet() { //NOSONAR return new TreeSet<>(); } /** * Creates a new instance of a TreeSet with the specified comparator. * * @param the type of elements in the set * @param comparator the comparator that will be used to order this set. * @return a new instance of a TreeSet * @see java.util.TreeSet#TreeSet(Comparator) */ public static TreeSet newTreeSet(final Comparator comparator) { //NOSONAR return new TreeSet<>(comparator); } /** * Creates a new instance of a TreeSet with the elements from the specified collection. * * @param the type of elements in the set * @param c the collection whose elements are to be placed into this set * @return a new instance of a TreeSet containing the elements from the specified collection * @see java.util.TreeSet#TreeSet(Collection) */ public static > TreeSet newTreeSet(final Collection c) { //NOSONAR return isEmpty(c) ? new TreeSet<>() : new TreeSet<>(c); } /** * Creates a new instance of a TreeSet with the elements from the specified sorted set. * * @param the type of elements in the set * @param sortedSet the sorted set whose elements are to be placed into this set * @return a new instance of a TreeSet containing the elements from the specified sorted set * @throws IllegalArgumentException if the specified {@code SortedSet} is {@code null}. * @see java.util.TreeSet#TreeSet(SortedSet) */ public static TreeSet newTreeSet(final SortedSet sortedSet) { //NOSONAR checkArgNotNull(sortedSet, cs.sortedSet); return new TreeSet<>(sortedSet); } /** * Creates a new instance of a concurrent hash set by {@code ConcurrentHashMap}. * * @param the type of elements in the set * @return a new instance of a concurrent hash set * @see Collections#newSetFromMap(Map) * @see java.util.concurrent.ConcurrentHashMap#ConcurrentHashMap() */ public static Set newConcurrentHashSet() { return newSetFromMap(new ConcurrentHashMap<>()); } /** * Creates a new instance of a concurrent hash set with the specified initial capacity. * * @param the type of elements in the set * @param initialCapacity the initial capacity of the set * @return a new instance of a concurrent hash set * @see Collections#newSetFromMap(Map) * @see java.util.concurrent.ConcurrentHashMap#ConcurrentHashMap(int) */ public static Set newConcurrentHashSet(final int initialCapacity) { return newSetFromMap(new ConcurrentHashMap<>(initialCapacity)); } /** * Creates a new instance of a concurrent hash set with the elements from the specified collection. * * @param the type of elements in the set * @param c the collection whose elements are to be placed into this set * @return a new instance of a concurrent hash set containing the elements from the specified collection * @see Collections#newSetFromMap(Map) * @see java.util.concurrent.ConcurrentHashMap#ConcurrentHashMap(int) */ public static Set newConcurrentHashSet(final Collection c) { final int size = size(c); final Set ret = newSetFromMap(new ConcurrentHashMap<>(size)); if (size > 0) { ret.addAll(c); } return ret; } /** * Returns a set backed by the specified map. * * @param the type of elements in the set * @param map the backing map * @return a set backed by the specified map * @see Collections#newSetFromMap(Map) */ public static Set newSetFromMap(final Map map) { return Collections.newSetFromMap(map); } /** * Creates a new instance of a Multiset. * * @param the type of elements in the multiset * @return a new instance of a Multiset */ public static Multiset newMultiset() { return new Multiset<>(); } /** * Creates a new instance of a Multiset with the specified initial capacity. * * @param the type of elements in the multiset * @param initialCapacity the initial capacity of the multiset * @return a new instance of a Multiset with the specified initial capacity */ public static Multiset newMultiset(final int initialCapacity) { return new Multiset<>(initialCapacity); } /** * Creates a new instance of a Multiset with the specified backed Map type for storing element/occurrence pairs. * * @param the type of elements in the multiset * @param valueMapType the class of the map to be used to store element/occurrence pairs * @return a new instance of a Multiset with the specified value map type */ @SuppressWarnings("rawtypes") public static Multiset newMultiset(final Class valueMapType) { return new Multiset<>(valueMapType); } /** * Creates a new instance of a Multiset with the specified {@code Supplier} which provides the map to store element/occurrence pairs. * * @param the type of elements in the multiset * @param mapSupplier the supplier that provides the map to be used to store element/occurrence pairs * @return a new instance of a Multiset with the specified value map type */ public static Multiset newMultiset(final Supplier> mapSupplier) { return new Multiset<>(mapSupplier); } /** * Creates a new instance of a Multiset with the elements from the specified collection. * * @param the type of elements in the multiset * @param c the collection whose elements are to be placed into this multiset * @return a new instance of a Multiset containing the elements from the specified collection */ public static Multiset newMultiset(final Collection c) { return new Multiset<>(c); } /** * Creates a new instance of an ArrayDeque. * * @param the type of elements in the deque * @return a new instance of an ArrayDeque */ public static ArrayDeque newArrayDeque() { //NOSONAR return new ArrayDeque<>(); } /** * Creates a new instance of an ArrayDeque with the specified initial capacity. * * @param the type of elements in the deque * @param numElements the initial capacity of the deque * @return a new instance of an ArrayDeque with the specified initial capacity */ public static ArrayDeque newArrayDeque(final int numElements) { //NOSONAR return new ArrayDeque<>(numElements); } /** * Creates a new instance of an ArrayDeque with the elements from the specified collection. * * @param the type of elements in the deque * @param c the collection whose elements are to be placed into this deque * @return a new instance of an ArrayDeque containing the elements from the specified collection */ public static ArrayDeque newArrayDeque(final Collection c) { //NOSONAR return new ArrayDeque<>(c); } /** * Creates a new entry with the specified key and value. * * @param the type of keys maintained by this entry * @param the type of mapped values * @param key the key to be associated with the entry * @param value the value to be associated with the entry * @return a new entry with the specified key and value */ public static Map.Entry newEntry(final K key, final V value) { return new AbstractMap.SimpleEntry<>(key, value); } /** * Creates a new immutable entry with the specified key and value. * * @param the type of keys maintained by this entry * @param the type of mapped values * @param key the key to be associated with the entry * @param value the value to be associated with the entry * @return a new immutable entry with the specified key and value */ public static ImmutableEntry newImmutableEntry(final K key, final V value) { return new ImmutableEntry<>(key, value); } /** * Creates a new instance of a HashMap. * * @param the type of keys maintained by this map * @param the type of mapped values * @return a new instance of a HashMap */ public static Map newHashMap() { return new HashMap<>(); } /** * Creates a new instance of a HashMap with the specified initial capacity. * * @param the type of keys maintained by this map * @param the type of mapped values * @param initialCapacity the initial capacity of the map * @return a new instance of a HashMap with the specified initial capacity */ public static Map newHashMap(final int initialCapacity) { return new HashMap<>(initHashCapacity(initialCapacity)); } /** * Creates a new instance of a HashMap with the entries from the specified map. * * @param the type of keys maintained by this map * @param the type of mapped values * @param m the map whose elements are to be placed into this map * @return a new instance of a HashMap containing the entries from the specified map */ public static Map newHashMap(final Map m) { return isEmpty(m) ? new HashMap<>() : new HashMap<>(m); } /** * Creates a new instance of a HashMap with the elements from the specified collection. * * @param the type of keys maintained by this map * @param the type of mapped values * @param c the collection whose elements are to be placed into this map * @param keyExtractor the function to extract a key from a collection element * @return a new instance of a HashMap containing the elements from the specified collection * @see #toMap(Iterable, Function) * @see #toMap(Iterable, Function, Function) * @see #toMap(Iterable, Function, Function, IntFunction) * @see #toMap(Iterable, Function, Function, BiFunction, IntFunction) */ public static Map newHashMap(final Collection c, final Function keyExtractor) throws IllegalArgumentException { // checkArgNotNull(keyExtractor); if (isEmpty(c)) { return new HashMap<>(); } final Map result = newHashMap(c.size()); for (final V v : c) { result.put(keyExtractor.apply(v), v); } return result; } /** * Creates a new instance of a LinkedHashMap. * * @param the type of keys maintained by this map * @param the type of mapped values * @return a new instance of a LinkedHashMap */ public static Map newLinkedHashMap() { return new LinkedHashMap<>(); } /** * Creates a new instance of a LinkedHashMap with the specified initial capacity. * * @param the type of keys maintained by this map * @param the type of mapped values * @param initialCapacity the initial capacity of the map * @return a new instance of a LinkedHashMap with the specified initial capacity */ public static Map newLinkedHashMap(final int initialCapacity) { return new LinkedHashMap<>(initHashCapacity(initialCapacity)); } /** * Creates a new instance of a LinkedHashMap with the entries from the specified map. * * @param the type of keys maintained by this map * @param the type of mapped values * @param m the map whose elements are to be placed into this map * @return a new instance of a LinkedHashMap containing the entries from the specified map */ public static Map newLinkedHashMap(final Map m) { return isEmpty(m) ? new LinkedHashMap<>() : new LinkedHashMap<>(m); } /** * Creates a new instance of a LinkedHashMap with the elements from the specified collection. * * @param the type of keys maintained by this map * @param the type of mapped values * @param c the collection whose elements are to be placed into this map * @param keyExtractor the function to extract a key from a collection element * @return a new instance of a LinkedHashMap containing the elements from the specified collection * @see #toMap(Iterable, Function) * @see #toMap(Iterable, Function, Function) * @see #toMap(Iterable, Function, Function, IntFunction) * @see #toMap(Iterable, Function, Function, BiFunction, IntFunction) */ public static Map newLinkedHashMap(final Collection c, final Function keyExtractor) throws IllegalArgumentException { if (isEmpty(c)) { return newLinkedHashMap(); } final Map result = newLinkedHashMap(c.size()); for (final V v : c) { result.put(keyExtractor.apply(v), v); } return result; } /** * Creates a new instance of a TreeMap. * * @param the type of keys maintained by this map, which must be comparable * @param the type of mapped values * @return a new instance of a TreeMap */ public static , V> TreeMap newTreeMap() { //NOSONAR return new TreeMap<>(); } /** * Creates a new instance of a TreeMap with the specified comparator. * * @param the type of the comparator * @param the type of keys maintained by this map * @param the type of mapped values * @param comparator the comparator that will be used to order this map * @return a new instance of a TreeMap with the specified comparator */ public static TreeMap newTreeMap(final Comparator comparator) { //NOSONAR return new TreeMap<>(comparator); } /** * Creates a new instance of a TreeMap with the entries from the specified map. * * @param the type of keys maintained by this map, which must be comparable * @param the type of mapped values * @param m the map whose elements are to be placed into this map * @return a new instance of a TreeMap containing the entries from the specified map */ public static , V> TreeMap newTreeMap(final Map m) { //NOSONAR return isEmpty(m) ? new TreeMap<>() : new TreeMap<>(m); } /** * Creates a new instance of a TreeMap with the entries from the specified sorted map. * * @param the type of keys maintained by this map * @param the type of mapped values * @param sortedMap the sorted map whose elements are to be placed into this map * @return a new instance of a TreeMap containing the entries from the specified sorted map * @throws IllegalArgumentException if the specified {@code SortedMap} is {@code null}. */ public static TreeMap newTreeMap(final SortedMap sortedMap) { //NOSONAR checkArgNotNull(sortedMap, cs.sortedMap); return new TreeMap<>(sortedMap); } /** * Creates a new instance of an IdentityHashMap. * * @param the type of keys maintained by this map * @param the type of mapped values * @return a new instance of an IdentityHashMap */ public static IdentityHashMap newIdentityHashMap() { //NOSONAR return new IdentityHashMap<>(); } /** * Creates a new instance of an IdentityHashMap with the specified initial capacity. * * @param the type of keys maintained by this map * @param the type of mapped values * @param initialCapacity the initial capacity of the map * @return a new instance of an IdentityHashMap with the specified initial capacity */ public static IdentityHashMap newIdentityHashMap(final int initialCapacity) { //NOSONAR return new IdentityHashMap<>(initHashCapacity(initialCapacity)); } /** * Creates a new instance of an IdentityHashMap with the entries from the specified map. * * @param the type of keys maintained by this map * @param the type of mapped values * @param m the map whose elements are to be placed into this map * @return a new instance of an IdentityHashMap containing the entries from the specified map */ public static IdentityHashMap newIdentityHashMap(final Map m) { //NOSONAR return isEmpty(m) ? new IdentityHashMap<>() : new IdentityHashMap<>(m); } /** * Creates a new instance of a ConcurrentHashMap. * * @param the type of keys maintained by this map * @param the type of mapped values * @return a new instance of a ConcurrentHashMap */ public static ConcurrentHashMap newConcurrentHashMap() { //NOSONAR return new ConcurrentHashMap<>(); } /** * Creates a new instance of a ConcurrentHashMap with the specified initial capacity. * * @param the type of keys maintained by this map * @param the type of mapped values * @param initialCapacity the initial capacity of the map * @return a new instance of a ConcurrentHashMap with the specified initial capacity */ public static ConcurrentHashMap newConcurrentHashMap(final int initialCapacity) { //NOSONAR return new ConcurrentHashMap<>(initHashCapacity(initialCapacity)); } /** * Creates a new instance of a ConcurrentHashMap with the entries from the specified map. * * @param the type of keys maintained by this map * @param the type of mapped values * @param m the map whose elements are to be placed into this map * @return a new instance of a ConcurrentHashMap containing the entries from the specified map */ public static ConcurrentHashMap newConcurrentHashMap(final Map m) { //NOSONAR return isEmpty(m) ? new ConcurrentHashMap<>() : new ConcurrentHashMap<>(m); } /** * Creates a new instance of a BiMap. * * @param the type of keys maintained by this map * @param the type of mapped values * @return a new instance of a BiMap */ public static BiMap newBiMap() { return new BiMap<>(); } /** * Creates a new instance of a BiMap with the specified initial capacity. * * @param the type of keys maintained by this map * @param the type of mapped values * @param initialCapacity the initial capacity of the map * @return a new instance of a BiMap with the specified initial capacity */ public static BiMap newBiMap(final int initialCapacity) { return new BiMap<>(initialCapacity); } /** * Creates a new instance of a BiMap with the specified initial capacity and load factor. * * @param the type of keys maintained by this map * @param the type of mapped values * @param initialCapacity the initial capacity of the map * @param loadFactor the load factor of the map * @return a new instance of a BiMap with the specified initial capacity and load factor */ public static BiMap newBiMap(final int initialCapacity, final float loadFactor) { return new BiMap<>(initialCapacity, loadFactor); } /** * Creates a new instance of a BiMap with the specified key map type which is used to create map to store key/value pairs and value map type which is used to create map to store value/key pairs. * * @param the type of keys maintained by this map * @param the type of mapped values * @param keyMapType the class of the map to be used to store key/value pairs * @param valueMapType the class of the map to be used to store value/key pairs * @return a new instance of a BiMap with the specified key and value map types */ @SuppressWarnings("rawtypes") public static BiMap newBiMap(final Class keyMapType, final Class valueMapType) { return new BiMap<>(keyMapType, valueMapType); } /** * Creates a new instance of a BiMap with the specified key map supplier which provides the map to store key/value pairs and value map supplier which provides the map to store value/key pairs. * * @param the type of keys maintained by this map * @param the type of mapped values * @param keyMapSupplier the supplier that provides the map to store key/value pairs * @param valueMapSupplier the supplier that provides the map to store value/key pairs * @return a new instance of a BiMap with the specified key and value map suppliers */ public static BiMap newBiMap(final Supplier> keyMapSupplier, final Supplier> valueMapSupplier) { return new BiMap<>(keyMapSupplier, valueMapSupplier); } /** * Creates a new instance of a Multimap with the specified map which provides the map to store key/value pairs and value supplier which provides the collection to store values. * * @param the type of keys maintained by this map * @param the type of elements in the collection * @param the type of collection that holds the elements * @param mapSupplier the supplier that provides the map to store key/value pairs * @param valueSupplier the supplier that provides the collection to store values * @return a new instance of a Multimap with the specified map and value suppliers */ public static > Multimap newMultimap(final Supplier> mapSupplier, final Supplier valueSupplier) { return new Multimap<>(mapSupplier, valueSupplier); } /** * Creates a new instance of a ListMultimap. * * @param the type of keys maintained by this map * @param the type of elements in the collection * @return a new instance of a ListMultimap */ public static ListMultimap newListMultimap() { return new ListMultimap<>(); } /** * Creates a new instance of a ListMultimap with the specified initial capacity. * * @param the type of keys maintained by this map * @param the type of elements in the collection * @param initialCapacity the initial capacity of the ListMultimap * @return a new instance of a ListMultimap with the specified initial capacity */ public static ListMultimap newListMultimap(final int initialCapacity) { return new ListMultimap<>(initialCapacity); } /** * Creates a new instance of a ListMultimap with the specified map type which is used to create the backed map for storing entries. * * @param the type of keys maintained by this map * @param the type of elements in the collection * @param mapType the class of the map to be used to store entries * @return a new instance of a ListMultimap with the specified map type */ @SuppressWarnings("rawtypes") public static ListMultimap newListMultimap(final Class mapType) { return new ListMultimap<>(mapType, ArrayList.class); } /** * Creates a new instance of a ListMultimap with the specified map type which is used to create the backed map for storing entries and value type which is used to create the backed list for storing values. * * @param the type of keys maintained by this map * @param the type of elements in the collection * @param mapType the class of the map to be used to store entries * @param valueType the class of the list to be used to store values * @return a new instance of a ListMultimap with the specified map type and value type */ @SuppressWarnings("rawtypes") public static ListMultimap newListMultimap(final Class mapType, final Class valueType) { return new ListMultimap<>(mapType, valueType); } /** * Creates a new instance of a ListMultimap with the specified map and value suppliers. * * @param the type of keys maintained by this map * @param the type of elements in the collection * @param mapSupplier the supplier that provides the map to store entries * @param valueSupplier the supplier that provides the list to store values * @return a new instance of a ListMultimap with the specified map and value suppliers */ public static ListMultimap newListMultimap(final Supplier>> mapSupplier, final Supplier> valueSupplier) { return new ListMultimap<>(mapSupplier, valueSupplier); } /** * Creates a new instance of a ListMultimap with the entries from the specified map. * * @param the type of keys maintained by this map * @param the type of elements in the collection * @param m the map whose elements are to be placed into this ListMultimap * @return a new instance of a ListMultimap containing the entries from the specified map */ public static ListMultimap newListMultimap(final Map m) { final ListMultimap multiMap = newListMultimap(size(m)); multiMap.put(m); return multiMap; } /** * Creates a new instance of a ListMultimap with the keys extracted from the specified collection by the specified {@code Function} and values from the specified collection. * * @param the type of elements in the collection * @param the type of keys maintained by this map * @param c the collection whose elements are to be placed into this ListMultimap * @param keyExtractor the function to extract keys from the specified collection elements * @return a new instance of a ListMultimap with the keys extracted from the specified collection elements */ public static ListMultimap newListMultimap(final Collection c, final Function keyExtractor) { return ListMultimap.create(c, keyExtractor); } /** * Creates a new instance of a ListMultimap with the keys and values extracted from the specified collection. * * @param the type of elements in the collection * @param the type of keys maintained by this map * @param the type of elements in the collection * @param c the collection whose elements are to be placed into this ListMultimap * @param keyExtractor the function to extract keys from the collection elements * @param valueExtractor the function to extract values from the collection elements * @return a new instance of a ListMultimap with the keys and values extracted from the specified collection */ public static ListMultimap newListMultimap(final Collection c, final Function keyExtractor, final Function valueExtractor) { return ListMultimap.create(c, keyExtractor, valueExtractor); } /** * Creates a new instance of a ListMultimap backed by a LinkedHashMap. * * @param the type of keys maintained by this map * @param the type of elements in the collection * @return a new instance of a ListMultimap backed by a LinkedHashMap */ public static ListMultimap newLinkedListMultimap() { return new ListMultimap<>(LinkedHashMap.class, ArrayList.class); } /** * Creates a new instance of a ListMultimap backed by a LinkedHashMap with the specified initial capacity. * * @param the type of keys maintained by this map * @param the type of elements in the collection * @param initialCapacity the initial capacity of the ListMultimap * @return a new instance of a ListMultimap backed by a LinkedHashMap with the specified initial capacity */ public static ListMultimap newLinkedListMultimap(final int initialCapacity) { return new ListMultimap<>(newLinkedHashMap(initialCapacity), ArrayList.class); } /** * Creates a new instance of a ListMultimap backed by a LinkedHashMap with the entries from the specified map. * * @param the type of keys maintained by this map * @param the type of elements in the collection * @param m the map whose elements are to be placed into this ListMultimap * @return a new instance of a ListMultimap containing the entries from the specified map */ public static ListMultimap newLinkedListMultimap(final Map m) { final ListMultimap multiMap = new ListMultimap<>(newLinkedHashMap(size(m)), ArrayList.class); multiMap.put(m); return multiMap; } /** * Creates a new instance of a ListMultimap backed by a SortedMap. * The keys in the map will be sorted according to their natural ordering. * * @param the type of keys maintained by this map, which must be comparable * @param the type of elements in the collection * @return a new instance of a ListMultimap backed by a SortedMap */ public static , E> ListMultimap newSortedListMultimap() { return new ListMultimap<>(new TreeMap<>(), ArrayList.class); } /** * Creates a new instance of a ListMultimap backed by a SortedMap with the entries from the specified map. * The keys in the map will be sorted according to their natural ordering. * * @param the type of keys maintained by this map, which must be comparable * @param the type of elements in the collection * @param m the map whose elements are to be placed into this ListMultimap * @return a new instance of a ListMultimap containing the entries from the specified map */ public static , E> ListMultimap newSortedListMultimap(final Map m) { final ListMultimap multiMap = new ListMultimap<>(new TreeMap<>(), ArrayList.class); multiMap.put(m); return multiMap; } /** * Creates a new instance of a SetMultimap. * * @param the type of keys maintained by this map * @param the type of elements in the collection * @return a new instance of a SetMultimap */ public static SetMultimap newSetMultimap() { return new SetMultimap<>(); } /** * Creates a new instance of a SetMultimap with the specified initial capacity. * * @param the type of keys maintained by this map * @param the type of elements in the collection * @param initialCapacity the initial capacity of the SetMultimap * @return a new instance of a SetMultimap with the specified initial capacity */ public static SetMultimap newSetMultimap(final int initialCapacity) { return new SetMultimap<>(initialCapacity); } /** * Creates a new instance of a SetMultimap with the specified map type which is used to create the backed map for storing entries. * * @param the type of keys maintained by this map * @param the type of elements in the collection * @param mapType the class of the map to be used to store entries * @return a new instance of a SetMultimap with the specified map type */ @SuppressWarnings("rawtypes") public static SetMultimap newSetMultimap(final Class mapType) { return new SetMultimap<>(mapType, HashSet.class); } /** * Creates a new instance of a SetMultimap with the specified map type which is used to create the backed map for storing entries and value type which is used to create the backed Set for storing values. * * @param the type of keys maintained by this map * @param the type of elements in the collection * @param mapType the class of the map to be used to store entries * @param valueType the class of the set to be used to store values * @return a new instance of a SetMultimap with the specified map type and value type */ @SuppressWarnings("rawtypes") public static SetMultimap newSetMultimap(final Class mapType, final Class valueType) { return new SetMultimap<>(mapType, valueType); } /** * Creates a new instance of a SetMultimap with the specified map and value suppliers. * * @param the type of keys maintained by this map * @param the type of elements in the collection * @param mapSupplier the supplier that provides the map to store entries * @param valueSupplier the supplier that provides the set to store values * @return a new instance of a SetMultimap with the specified map and value suppliers */ public static SetMultimap newSetMultimap(final Supplier>> mapSupplier, final Supplier> valueSupplier) { return new SetMultimap<>(mapSupplier, valueSupplier); } /** * Creates a new instance of a SetMultimap with the entries from the specified map. * * @param the type of keys maintained by this map * @param the type of elements in the collection * @param m the map whose elements are to be placed into this SetMultimap * @return a new instance of a SetMultimap containing the entries from the specified map */ public static SetMultimap newSetMultimap(final Map m) { final SetMultimap multiMap = newSetMultimap(size(m)); multiMap.put(m); return multiMap; } /** * Creates a new instance of a SetMultimap with the keys extracted from the specified collection by the specified {@code Function} and values from the specified collection. * * @param the type of elements in the collection * @param the type of keys maintained by this map * @param c the collection whose elements are to be placed into this SetMultimap * @param keyExtractor the function to extract keys from the specified collection elements * @return a new instance of a SetMultimap with the keys extracted from the specified collection elements */ public static SetMultimap newSetMultimap(final Collection c, final Function keyExtractor) { return SetMultimap.create(c, keyExtractor); } /** * Creates a new instance of a SetMultimap with the keys and values extracted from the specified collection. * * @param the type of elements in the collection * @param the type of keys maintained by this map * @param the type of elements in the collection * @param c the collection whose elements are to be placed into this SetMultimap * @param keyExtractor the function to extract keys from the collection elements * @param valueExtractor the function to extract values from the collection elements * @return a new instance of a SetMultimap with the keys and values extracted from the specified collection */ public static SetMultimap newSetMultimap(final Collection c, final Function keyExtractor, final Function valueExtractor) { return SetMultimap.create(c, keyExtractor, valueExtractor); } /** * Creates a new instance of a SetMultimap backed by a LinkedHashMap. * * @param the type of keys maintained by this map * @param the type of elements in the collection * @return a new instance of a SetMultimap backed by a LinkedHashMap */ public static SetMultimap newLinkedSetMultimap() { return new SetMultimap<>(LinkedHashMap.class, HashSet.class); } /** * Creates a new instance of a SetMultimap backed by a LinkedHashMap with the specified initial capacity. * * @param the type of keys maintained by this map * @param the type of elements in the collection * @param initialCapacity the initial capacity of the SetMultimap * @return a new instance of a SetMultimap backed by a LinkedHashMap with the specified initial capacity */ public static SetMultimap newLinkedSetMultimap(final int initialCapacity) { return new SetMultimap<>(newLinkedHashMap(initialCapacity), HashSet.class); } /** * Creates a new instance of a SetMultimap backed by a LinkedHashMap with the entries from the specified map. * * @param the type of keys maintained by this map * @param the type of elements in the collection * @param m the map whose elements are to be placed into this SetMultimap * @return a new instance of a SetMultimap containing the entries from the specified map */ public static SetMultimap newLinkedSetMultimap(final Map m) { final SetMultimap multiMap = new SetMultimap<>(newLinkedHashMap(size(m)), HashSet.class); multiMap.put(m); return multiMap; } /** * Creates a new instance of a SetMultimap backed by a SortedMap. * The keys in the map will be sorted according to their natural ordering. * * @param the type of keys maintained by this map, which must be comparable * @param the type of elements in the collection * @return a new instance of a SetMultimap backed by a SortedMap */ public static , E> SetMultimap newSortedSetMultimap() { return new SetMultimap<>(new TreeMap<>(), HashSet.class); } /** * Creates a new instance of a SetMultimap backed by a SortedMap with the entries from the specified map. * The keys in the map will be sorted according to their natural ordering. * * @param the type of keys maintained by this map, which must be comparable * @param the type of elements in the collection * @param m the map whose elements are to be placed into this SetMultimap * @return a new instance of a SetMultimap containing the entries from the specified map */ public static , E> SetMultimap newSortedSetMultimap(final Map m) { final SetMultimap multiMap = new SetMultimap<>(new TreeMap<>(), HashSet.class); multiMap.put(m); return multiMap; } static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; static final int MAX_HASH_LENGTH = (int) (MAX_ARRAY_SIZE / 1.25) - 1; /** * Creates a new empty DataSet. * * The DataSet is a data structure that stores data in a tabular format, similar to a table in a database. * This method creates a DataSet with no rows or columns. * * @return A new empty DataSet. * @see DataSet#empty() */ public static DataSet newEmptyDataSet() { return new RowDataSet(new ArrayList<>(), new ArrayList<>()); } /** * Creates a new empty DataSet with the specified properties. * * The DataSet is a data structure that stores data in a tabular format, similar to a table in a database. * This method creates a DataSet with no rows or columns, but with the specified properties. * * @param properties A map representing the properties of the DataSet. The keys are property names and the values are the corresponding property values. * @return A new empty DataSet with the specified properties. * @see DataSet#empty() */ static DataSet newEmptyDataSet(final Map properties) { return new RowDataSet(new ArrayList<>(), new ArrayList<>(), properties); } /** * Creates a new empty DataSet with the specified column names. * * The DataSet is a data structure that stores data in a tabular format, similar to a table in a database. * This method creates a DataSet with no rows, but with the specified column names. * * @param columnNames A collection of strings representing the names of the columns in the DataSet. * @return A new empty DataSet with the specified column names. * @see DataSet#empty() */ public static DataSet newEmptyDataSet(final Collection columnNames) { return newEmptyDataSet(columnNames, null); } /** * Creates a new empty DataSet with the specified column names and properties. * * The DataSet is a data structure that stores data in a tabular format, similar to a table in a database. * This method creates a DataSet with no rows, but with the specified column names and properties. * * @param columnNames A collection of strings representing the names of the columns in the DataSet. * @param properties A map representing the properties of the DataSet. The keys are property names and the values are the corresponding property values. * @return A new empty DataSet with the specified column names and properties. * @see DataSet#empty() */ public static DataSet newEmptyDataSet(final Collection columnNames, final Map properties) { if (isEmpty(columnNames)) { return newEmptyDataSet(properties); } final List> columnList = new ArrayList<>(columnNames.size()); for (int i = 0, size = columnNames.size(); i < size; i++) { columnList.add(new ArrayList<>()); } return new RowDataSet(new ArrayList<>(columnNames), columnList, properties); } /** * Creates a new DataSet with the specified rows. * * The DataSet is a data structure that stores data in a tabular format, similar to a table in a database. * The rows parameter is a collection where each item represents a row in the DataSet. * * @param rows A collection of objects representing the data in the DataSet. Each object is a row which can be: Map/Bean. * @return A new DataSet with the specified rows. * @throws IllegalArgumentException If the provided rows do not align properly. * @see DataSet#rows(Collection, Object[][]) * @see DataSet#rows(Collection, Collection) * @see DataSet#columns(Collection, Object[][]) * @see DataSet#columns(Collection, Collection) */ public static DataSet newDataSet(final Collection rows) throws IllegalArgumentException { return newDataSet(rows, null); } /** * Creates a new DataSet with the specified rows and properties. * * The DataSet is a data structure that stores data in a tabular format, similar to a table in a database. * The rows parameter is a collection where each item represents a row in the DataSet. * The properties parameter is a map where each entry represents a property of the DataSet. * * @param rows A collection of objects representing the data in the DataSet. Each object is a row which can be: Map/Bean. * @param properties A map of properties for the DataSet. Each key is a property name and each value is the property value. * @return A new DataSet with the specified rows and properties. * @throws IllegalArgumentException If the provided rows and properties do not align properly. * @see DataSet#rows(Collection, Object[][]) * @see DataSet#rows(Collection, Collection) * @see DataSet#columns(Collection, Object[][]) * @see DataSet#columns(Collection, Collection) */ public static DataSet newDataSet(final Collection rows, final Map properties) throws IllegalArgumentException { if (isEmpty(rows)) { return newEmptyDataSet(properties); } final Object firstElement = firstOrNullIfEmpty(rows); if (firstElement == null) { throw new IllegalArgumentException("Column name list cannot be obtained from row list because its first element is null"); } final Class cls = firstElement.getClass(); if (ClassUtil.isBeanClass(cls)) { final List columnNames = ClassUtil.getPropNameList(cls); return newDataSet(columnNames, rows, properties); } else if (firstElement instanceof Map) { final List columnNames = newArrayList(((Map) firstElement).keySet()); return newDataSet(columnNames, rows, properties); } else { throw new IllegalArgumentException("Unsupported row type: " + cls.getName()); } } /** * Creates a new DataSet with the specified column names and rows. * * The DataSet is a data structure that stores data in a tabular format, similar to a table in a database. * Each item in the columnNames collection represents a column in the DataSet. * The rows parameter is a collection where each item represents a row in the DataSet. * The order of elements in each row should correspond to the order of column names. * * @param columnNames A collection of strings representing the names of the columns in the DataSet. * @param rows A collection of objects representing the data in the DataSet. Each object is a row which can be: Map/Bean/Array/List. * @return A new DataSet with the specified column names and rows. * @throws IllegalArgumentException If the length of columnNames is zero or not align with row list. * @see DataSet#rows(Collection, Object[][]) * @see DataSet#rows(Collection, Collection) * @see DataSet#columns(Collection, Object[][]) * @see DataSet#columns(Collection, Collection) */ public static DataSet newDataSet(final Collection columnNames, final Collection rows) throws IllegalArgumentException { return newDataSet(columnNames, rows, null); } /** * Creates a new DataSet with the specified column names, rows, and properties. * * The DataSet is a data structure that stores data in a tabular format, similar to a table in a database. * Each item in the columnNames collection represents a column in the DataSet. * The rows parameter is a collection where each item represents a row in the DataSet. * The order of elements in each row should correspond to the order of column names. * The properties parameter is a map where each entry represents a property of the DataSet. * * @param columnNames A collection of strings representing the names of the columns in the DataSet. * @param rows A collection of objects representing the data in the DataSet. Each object is a row which can be: Map/Bean/Array/List. * @param properties A map of properties for the DataSet. Each key is a property name and each value is the property value. * @return A new DataSet with the specified column names, rows, and properties. * @throws IllegalArgumentException If the length of columnNames is zero or not align with row list. * @see DataSet#rows(Collection, Object[][]) * @see DataSet#rows(Collection, Collection) * @see DataSet#columns(Collection, Object[][]) * @see DataSet#columns(Collection, Collection) */ public static DataSet newDataSet(final Collection columnNames, final Collection rows, final Map properties) throws IllegalArgumentException { checkArgNotEmpty(columnNames, cs.columnNames); // if (isEmpty(columnNames) && isEmpty(rows)) { // // throw new IllegalArgumentException("Column name list and row list cannot be both null or empty"); // return newEmptyDataSet(properties); // } if (isEmpty(rows)) { return newEmptyDataSet(columnNames, properties); } // int startRowIndex = 0; // if (isEmpty(columnNames)) { // final Object firstElement = firstOrNullIfEmpty(rows); // // if (firstElement == null) { // // return newEmptyDataSet(properties); // throw new IllegalArgumentException("Column name list cannot be obtained from row list because its first element is null"); // } // // final Class cls = firstElement.getClass(); // final Type type = typeOf(cls); // // if (type.isMap()) { // columnNames = new ArrayList<>(((Map) firstElement).keySet()); // } else if (type.isBean()) { // columnNames = new ArrayList<>(ClassUtil.getPropNameList(cls)); // } else { // // if (type.isArray()) { // // final Object[] a = (Object[]) firstNonNullRow; // // columnNames = new ArrayList<>(a.length); // // // // for (final Object e : a) { // // columnNames.add(stringOf(e)); // // } // // } else if (type.isCollection()) { // // final Collection c = (Collection) firstNonNullRow; // // columnNames = new ArrayList<>(c.size()); // // // // for (final Object e : c) { // // columnNames.add(stringOf(e)); // // } // // } else { // // throw new IllegalArgumentException("Unsupported header type: " + type.name() + " when specified 'columnNames' is null or empty"); // // } // // // // startRowIndex = 1; // // throw new IllegalArgumentException("Unsupported header type: " + type.name() + " when specified 'columnNames' is null or empty"); // } // // if (isEmpty(columnNames)) { // throw new IllegalArgumentException("Column name list cannot be obtained from row list because it's empty or null"); // } // } // final int rowCount = rows.size() - startRowIndex; final int rowCount = rows.size(); final int columnCount = columnNames.size(); final List columnNameList = new ArrayList<>(columnNames); final List> columnList = new ArrayList<>(columnCount); for (int i = 0; i < columnCount; i++) { columnList.add(new ArrayList<>(rowCount)); } Type type = null; for (final Object row : rows) { // if (startRowIndex-- > 0) { // // skip // continue; // } if (row == null) { for (int i = 0; i < columnCount; i++) { columnList.get(i).add(null); } continue; } final Class cls = row.getClass(); type = typeOf(cls); if (type.isMap()) { final Map props = (Map) row; for (int i = 0; i < columnCount; i++) { columnList.get(i).add(props.get(columnNameList.get(i))); } } else if (type.isBean()) { final BeanInfo beanInfo = ParserUtil.getBeanInfo(cls); PropInfo propInfo = null; for (int i = 0; i < columnCount; i++) { propInfo = beanInfo.getPropInfo(columnNameList.get(i)); if (propInfo == null) { columnList.get(i).add(null); } else { columnList.get(i).add(propInfo.getPropValue(row)); } } } else if (type.isArray()) { if (type.isPrimitiveArray()) { for (int i = 0; i < columnCount; i++) { columnList.get(i).add(Array.get(row, i)); } } else { final Object[] array = (Object[]) row; for (int i = 0; i < columnCount; i++) { columnList.get(i).add(array[i]); } } } else if (type.isCollection()) { final Iterator it = ((Collection) row).iterator(); for (int i = 0; i < columnCount; i++) { columnList.get(i).add(it.next()); } } else { throw new IllegalArgumentException( "Unsupported row type: " + ClassUtil.getCanonicalClassName(row.getClass()) + ". Only array, collection, map and bean are supported"); } } return new RowDataSet(columnNameList, columnList, properties); } /** * Creates a new DataSet with the specified column names and rows. * * The DataSet is a data structure that stores data in a tabular format, similar to a table in a database. * Each item in the columnNames collection represents a column in the DataSet. * The rowList parameter is a 2D array where each subarray represents a row in the DataSet. * The order of elements in each row should correspond to the order of column names. * * @param columnNames A collection of strings representing the names of the columns in the DataSet. * @param rowList A 2D array of objects representing the data in the DataSet. Each subarray is a row. * @return A new DataSet with the specified column names and rows. * @throws IllegalArgumentException If the length of columnNames is zero or not equal to the length of the subarrays in rowList. * @see DataSet#rows(Collection, Object[][]) * @see DataSet#rows(Collection, Collection) * @see DataSet#columns(Collection, Object[][]) * @see DataSet#columns(Collection, Collection) */ public static DataSet newDataSet(final Collection columnNames, final Object[][] rowList) throws IllegalArgumentException { checkArgNotEmpty(columnNames, cs.columnNames); // if (isEmpty(columnNames) && isEmpty(rowList)) { // // throw new IllegalArgumentException("Column name list and row list cannot be both null or empty"); // return newEmptyDataSet(); // } if (isEmpty(rowList)) { return newEmptyDataSet(columnNames); } checkArgument(size(columnNames) == len(rowList[0]), "length of 'columnNames' is not equals to length of 'rowList[0]'"); return newDataSet(columnNames, asList(rowList)); } /** * Creates a new DataSet from the provided Map. * The DataSet will have two columns: one for keys and one for values from the Map. * * @param keyColumnName The name of the column for the keys from the Map. * @param valueColumnName The name of the column for the values from the Map. * @param m The Map to convert into a DataSet. * @return A new DataSet with two columns: one for keys and one for values from the Map. */ public static DataSet newDataSet(final String keyColumnName, final String valueColumnName, final Map m) { final List keyColumn = new ArrayList<>(m.size()); final List valueColumn = new ArrayList<>(m.size()); for (final Map.Entry entry : m.entrySet()) { keyColumn.add(entry.getKey()); valueColumn.add(entry.getValue()); } final List columnNameList = asList(keyColumnName, valueColumnName); final List> columnList = asList(keyColumn, valueColumn); return newDataSet(columnNameList, columnList); } /** * Creates a new DataSet from the provided Map. * * The DataSet will have as many columns as there are entries in the Map. * The column names are the keys from the Map. * Each column corresponds to a Collection in the Map. * If a column has fewer rows than the maximum number of rows, the missing rows will be filled with {@code null} values. * Eventually all the columns will have the same number of rows. * * @param The type of the Collection values in the Map. * @param map The Map to convert into a DataSet. The keys of the map represent the column names and the values (which are collections) represent the data in the columns. * @return A new DataSet with columns created from the Map. */ public static > DataSet newDataSet(final Map map) { if (isEmpty(map)) { return newEmptyDataSet(); } int maxColumnLen = 0; for (final C v : map.values()) { maxColumnLen = N.max(maxColumnLen, size(v)); } final List columnNameList = new ArrayList<>(map.keySet()); final List> columnList = new ArrayList<>(columnNameList.size()); List column = null; for (final C v : map.values()) { column = new ArrayList<>(maxColumnLen); if (notEmpty(v)) { column.addAll(v); } if (column.size() < maxColumnLen) { fill(column, column.size(), maxColumnLen, null); } columnList.add(column); } return new RowDataSet(columnNameList, columnList); } /** * Creates a new DataSet with single column from the provided Collection. * The DataSet will have one column with the provided column name. * The data in the column is the data from the provided Collection. * * @param columnName The name of the column in the DataSet. * @param column The Collection to convert into a DataSet column. * @return A new DataSet with one column containing the data from the provided Collection. * @throws IllegalArgumentException if the provided columnName is empty. */ public static DataSet newDataSet(final String columnName, final Collection column) throws IllegalArgumentException { checkArgNotEmpty(columnName, cs.columnName); final List columnNameList = asList(columnName); final List> columnList = new ArrayList<>(1); columnList.add(newArrayList(column)); return new RowDataSet(columnNameList, columnList); } /** * Merges two given DataSets into a single DataSet. * * @param a The first DataSet to be merged. * @param b The second DataSet to be merged. * @return A new DataSet which is the result of merging DataSet a and DataSet b. * @throws IllegalArgumentException if either a or b is {@code null}. */ public static DataSet merge(@NotNull final DataSet a, @NotNull final DataSet b) throws IllegalArgumentException { checkArgNotNull(a); checkArgNotNull(b); return a.merge(b); } /** * Merges three given DataSets into a single DataSet. * * @param a The first DataSet to be merged. * @param b The second DataSet to be merged. * @param c The third DataSet to be merged. * @return A new DataSet which is the result of merging DataSet a, b and c. * @throws IllegalArgumentException if either a, b or c is {@code null}. */ public static DataSet merge(@NotNull final DataSet a, @NotNull final DataSet b, @NotNull final DataSet c) throws IllegalArgumentException { checkArgNotNull(a); checkArgNotNull(b); checkArgNotNull(c); return merge(asList(a, b, c)); } /** * Merges a collection of DataSets into a single DataSet. * * @param dss The collection of DataSets to be merged. * @return A new DataSet which is the result of merging all the DataSets in the provided collection. * @throws IllegalArgumentException if the provided collection is {@code null}. */ public static DataSet merge(final Collection dss) throws IllegalArgumentException { return merge(dss, false); } /** * Merges a collection of DataSets into a single DataSet. * * @param dss The collection of DataSets to be merged. * @param requiresSameColumns A boolean flag that indicates whether the DataSets in the collection should have the same columns. * If set to {@code true}, all DataSets in the collection must have the same columns. * If set to {@code false}, the DataSets in the collection can have different columns. * @return A new DataSet which is the result of merging all the DataSets in the provided collection. * @throws IllegalArgumentException if the provided collection is {@code null} or {@code requiresSameColumns} is {@code true} and the {@code DataSets} in {@code dss} don't have the same the same column names. */ public static DataSet merge(final Collection dss, final boolean requiresSameColumns) throws IllegalArgumentException { if (requiresSameColumns && size(dss) > 1) { final Iterator iter = dss.iterator(); final DataSet firstDataSet = iter.next(); if (iter.hasNext()) { checkIfColumnNamesAreSame(firstDataSet, iter.next()); } } if (isEmpty(dss)) { return newEmptyDataSet(); } else if (dss.size() == 1) { return dss.iterator().next().copy(); } else if (dss.size() == 2) { final Iterator iter = dss.iterator(); return iter.next().merge(iter.next()); } else { final Set columnNameSet = newLinkedHashSet(); final Map props = new HashMap<>(); int totalSize = 0; for (final DataSet ds : dss) { columnNameSet.addAll(ds.columnNameList()); totalSize += ds.size(); if (notEmpty(ds.properties())) { props.putAll(ds.properties()); } } final int newColumnCount = columnNameSet.size(); final List newColumnNameList = new ArrayList<>(columnNameSet); final List> newColumnList = new ArrayList<>(newColumnCount); for (int i = 0; i < newColumnCount; i++) { newColumnList.add(new ArrayList<>(totalSize)); } for (final DataSet ds : dss) { if (ds.isEmpty()) { continue; } List column = null; for (int i = 0; i < newColumnCount; i++) { column = newColumnList.get(i); if (ds.containsColumn(newColumnNameList.get(i))) { column.addAll(ds.getColumn(newColumnNameList.get(i))); } else { fill(column, column.size(), column.size() + ds.size(), null); } } } return new RowDataSet(newColumnNameList, newColumnList, props); } } private static void checkIfColumnNamesAreSame(final DataSet a, final DataSet b) { if (!(a.columnNameList().size() == b.columnNameList().size() && a.columnNameList().containsAll(b.columnNameList()) && b.columnNameList().containsAll(a.columnNameList()))) { throw new IllegalArgumentException("These two DataSets don't have same column names: " + a.columnNameList() + ", " + b.columnNameList()); } } /** * Converts the specified collection to an array. * Returns an empty array if the specified collection is {@code null} or empty. * * @param c the collection to be converted to an array * @return an array containing all the elements in the specified collection */ public static Object[] toArray(final Collection c) { if (isEmpty(c)) { return EMPTY_OBJECT_ARRAY; } return c.toArray(new Object[0]); } /** * Converts the specified range in the specified collection into an array. * * @param c The collection to be converted into an array. * @param fromIndex The starting (inclusive) index of the range to be converted. * @param toIndex The ending (exclusive) index of the range to be converted. * @return An array containing the elements of the specified range of the collection. * @throws IndexOutOfBoundsException if the provided indices are out of the collection's range. */ @SuppressWarnings("rawtypes") public static Object[] toArray(final Collection c, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, size(c)); if (isEmpty(c)) { return EMPTY_OBJECT_ARRAY; } else if (fromIndex == 0 || toIndex == c.size()) { return c.toArray(new Object[0]); } else if (c instanceof List) { return ((List) c).subList(fromIndex, toIndex).toArray(new Object[toIndex - fromIndex]); } else { final Object[] res = new Object[toIndex - fromIndex]; final Iterator iter = c.iterator(); int idx = 0; while (idx < fromIndex && iter.hasNext()) { iter.next(); idx++; } while (idx < toIndex && iter.hasNext()) { res[idx - fromIndex] = iter.next(); idx++; } return res; } } /** * Converts a collection into an array. If the provided array is large enough to hold the elements of the collection, * it is filled with the collection's elements, otherwise, a new array of the same runtime type is allocated for this purpose. * * @param The type of the array. * @param The type of the elements in the collection. It must extend or be the same as the type of the array. * @param c The collection to be converted into an array. * @param a The array into which the elements of the collection are to be stored, if it is big enough; otherwise, a new array of the same runtime type is allocated for this purpose. * @return The array containing the elements of the collection. If the provided array was large enough to hold the collection's elements, it is the same as the provided array. * @throws IllegalArgumentException if the specified {@code Array} is {@code null}. */ public static A[] toArray(final Collection c, @NotNull final A[] a) throws IndexOutOfBoundsException, IllegalArgumentException { checkArgNotNull(a); if (isEmpty(c)) { return a; } return c.toArray(a); } /** * Converts the specified range in the specified collection into an array. If the provided array is large enough to hold the elements of the collection, * it is filled with the collection's elements, otherwise, a new array of the same runtime type is allocated for this purpose. * * @param The type of the array. * @param The type of the elements in the collection. It must extend or be the same as the type of the array. * @param c The collection to be converted into an array. * @param fromIndex The starting (inclusive) index of the range to be converted. * @param toIndex The ending (exclusive) index of the range to be converted. * @param a The array into which the elements of the collection are to be stored, if it is big enough; otherwise, a new array of the same runtime type is allocated for this purpose. * @return The array containing the elements of the specified portion of the collection. If the provided array was large enough to hold the collection's elements, it is the same as the provided array. * @throws IllegalArgumentException if the specified {@code Array} is {@code null}. */ public static A[] toArray(final Collection c, final int fromIndex, final int toIndex, @NotNull final A[] a) throws IllegalArgumentException { checkFromToIndex(fromIndex, toIndex, size(c)); checkArgNotNull(a); if (isEmpty(c)) { return a; } else if (fromIndex == 0 || toIndex == c.size()) { return c.toArray(a); } else if (c instanceof List) { return ((List) c).subList(fromIndex, toIndex).toArray(a); } else { final A[] res = a.length >= toIndex - fromIndex ? a : (A[]) newArray(a.getClass().getComponentType(), toIndex - fromIndex); final Iterator iter = c.iterator(); int idx = 0; while (idx < fromIndex && iter.hasNext()) { iter.next(); idx++; } while (idx < toIndex && iter.hasNext()) { res[idx - fromIndex] = iter.next(); idx++; } return res; } } /** * Converts a collection into an array using a provided array supplier function. * The array supplier function is responsible for creating a new array of the appropriate type and size. * * @param The type of the array. * @param The type of the elements in the collection. It must extend or be the same as the type of the array. * @param c The collection to be converted into an array. * @param arraySupplier The function to generate a new array of the appropriate type and size. */ public static A[] toArray(final Collection c, final IntFunction arraySupplier) { if (isEmpty(c)) { return arraySupplier.apply(0); } return toArray(c, arraySupplier); } /** * Converts the specified range in the specified collection into an array using a provided array supplier function. * The array supplier function is responsible for creating a new array of the appropriate type and size. * * @param The type of the array. * @param The type of the elements in the collection. It must extend or be the same as the type of the array. * @param c The collection to be converted into an array. * @param fromIndex The starting (inclusive) index of the portion to be converted. * @param toIndex The ending (exclusive) index of the portion to be converted. * @param arraySupplier The function to generate a new array of the appropriate type and size. * @return The array containing the elements of the specified portion of the collection. * @throws IndexOutOfBoundsException if the specified {@code fromIndex} or {@code toIndex} is out of the collection's range. */ public static A[] toArray(final Collection c, final int fromIndex, final int toIndex, final IntFunction arraySupplier) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, size(c)); if (isEmpty(c)) { return arraySupplier.apply(0); } else if (fromIndex == 0 || toIndex == c.size()) { return c.toArray(arraySupplier.apply(c.size())); } else if (c instanceof List) { return ((List) c).subList(fromIndex, toIndex).toArray(arraySupplier.apply(toIndex - fromIndex)); } else { final A[] res = arraySupplier.apply(toIndex - fromIndex); final Iterator iter = c.iterator(); int idx = 0; while (idx < fromIndex && iter.hasNext()) { iter.next(); idx++; } while (idx < toIndex && iter.hasNext()) { res[idx - fromIndex] = iter.next(); idx++; } return res; } } /** * Converts a collection into an array of a specified type. * * @param The type of the array. * @param The type of the elements in the collection. It must extend or be the same as the type of the array. * @param c The collection to be converted into an array. * @param targetType The Class object representing the type of the array to be returned. * @return The array containing the elements of the collection. * @throws IllegalArgumentException if the specified {@code Class} is {@code null}. */ public static A[] toArray(final Collection c, @NotNull final Class targetType) throws IndexOutOfBoundsException, IllegalArgumentException { checkArgNotNull(targetType); if (isEmpty(c)) { return newArray(targetType.getComponentType(), 0); } return c.toArray((A[]) newArray(targetType.getComponentType(), c.size())); } /** * Converts the specified range in the specified collection into an array of a specified type. * * @param The type of the array. * @param The type of the elements in the collection. It must extend or be the same as the type of the array. * @param c The collection to be converted into an array. * @param fromIndex The starting (inclusive) index of the range to be converted. * @param toIndex The ending (exclusive) index of the range to be converted. * @param targetType The Class object representing the type of the array to be returned. * @return The array containing the elements of the specified portion of the collection. * @throws IllegalArgumentException if the specified {@code Class} is {@code null}. * @throws IndexOutOfBoundsException if the specified {@code fromIndex} or {@code toIndex} is out of the collection's range. */ public static A[] toArray(final Collection c, final int fromIndex, final int toIndex, @NotNull final Class targetType) throws IllegalArgumentException { checkArgNotNull(targetType); checkFromToIndex(fromIndex, toIndex, size(c)); final A[] res = newArray(targetType.getComponentType(), toIndex - fromIndex); if (isEmpty(c)) { return res; } else if (fromIndex == 0 || toIndex == c.size()) { return c.toArray(res); } else if (c instanceof List) { return ((List) c).subList(fromIndex, toIndex).toArray(res); } else { final Iterator iter = c.iterator(); int idx = 0; while (idx < fromIndex && iter.hasNext()) { iter.next(); idx++; } while (idx < toIndex && iter.hasNext()) { res[idx - fromIndex] = iter.next(); idx++; } return res; } } /** * Converts a collection of Boolean objects to a boolean array. * * @param c the collection of Boolean objects to be converted * @return a boolean array containing the primitive boolean values from the collection */ public static boolean[] toBooleanArray(final Collection c) { return toBooleanArray(c, false); } /** * Converts the specified range of the specified Boolean collection to a boolean array. * * @param c the collection of Boolean objects to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return a boolean array containing the primitive boolean values from the specified range of the collection */ public static boolean[] toBooleanArray(final Collection c, final int fromIndex, final int toIndex) { return toBooleanArray(c, fromIndex, toIndex, false); } /** * Converts a collection of Boolean objects to a boolean array. * * @param c the collection of Boolean objects to be converted * @param defaultForNull the default boolean value to use if a Boolean object in the collection is null * @return a boolean array containing the primitive boolean values from the collection */ public static boolean[] toBooleanArray(final Collection c, final boolean defaultForNull) { return toBooleanArray(c, 0, size(c), defaultForNull); } /** * Converts the specified range of the specified Boolean collection to a boolean array. * * @param c the collection of Boolean objects to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @param defaultForNull the default boolean value to use if a Boolean object in the collection is null * @return a boolean array containing the primitive boolean values from the specified range of the collection * @throws IndexOutOfBoundsException if the specified indices are out of the collection's range */ public static boolean[] toBooleanArray(final Collection c, final int fromIndex, final int toIndex, final boolean defaultForNull) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, size(c)); if (fromIndex == toIndex) { return EMPTY_BOOLEAN_ARRAY; } final int len = toIndex - fromIndex; final boolean[] result = new boolean[len]; if (c instanceof final List list && c instanceof RandomAccess) { Boolean val = null; for (int i = 0; i < len; i++) { if ((val = list.get(i + fromIndex)) == null) { result[i] = defaultForNull; } else { result[i] = val; } } } else { final Iterator iter = c.iterator(); if (fromIndex > 0) { int offset = 0; while (offset++ < fromIndex) { iter.next(); } } Boolean val = null; for (int i = 0; i < len; i++) { if ((val = iter.next()) == null) { result[i] = defaultForNull; } else { result[i] = val; } } } return result; } /** * Converts a byte array to a boolean array. * Each byte with positive value({@code > 0}) is converted to a boolean value {@code true}, {@code 0} and negative value to {@code false}. * * @param a the byte array to be converted * @return a boolean array with the same length as the input array, or an empty boolean array if the input array is {@code null} or empty */ public static boolean[] toBooleanArray(final byte[] a) { if ((a == null) || (a.length == 0)) { return EMPTY_BOOLEAN_ARRAY; // return null; // NOSONAR } else { final int len = a.length; final boolean[] result = new boolean[len]; for (int i = 0; i < len; i++) { result[i] = a[i] > Numbers.BYTE_ZERO; } return result; } } /** * Converts an integer array to a boolean array. * Each integer with positive value({@code > 0}) is converted to a boolean value {@code true}, {@code 0} and negative value to {@code false}. * * @param a the integer array to be converted * @return a boolean array with the same length as the input array, or an empty boolean array if the input array is {@code null} or empty */ public static boolean[] toBooleanArray(final int[] a) { if ((a == null) || (a.length == 0)) { return EMPTY_BOOLEAN_ARRAY; // return null; // NOSONAR } else { final int len = a.length; final boolean[] result = new boolean[len]; for (int i = 0; i < len; i++) { result[i] = a[i] > 0; } return result; } } /** * Converts a collection of Character objects to a char array. * * @param c the collection of Character objects to be converted * @return a char array containing the primitive char values from the collection */ public static char[] toCharArray(final Collection c) { return toCharArray(c, (char) 0); } /** * Converts the specified range of the specified character collection to a char array. * * @param c the collection of Character objects to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return a char array containing the primitive char values from the specified range of the collection * @throws IndexOutOfBoundsException if the specified indices are out of the collection's range */ public static char[] toCharArray(final Collection c, final int fromIndex, final int toIndex) { return toCharArray(c, fromIndex, toIndex, (char) 0); } /** * Converts a collection of Character objects to a char array. * * @param c the collection of Character objects to be converted * @param defaultForNull the default char value to use if a Character object in the collection is null * @return a char array containing the primitive char values from the collection */ public static char[] toCharArray(final Collection c, final char defaultForNull) { return toCharArray(c, 0, size(c), defaultForNull); } /** * Converts the specified range of the specified character collection to a char array. * * @param c the collection of Character objects to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @param defaultForNull the default char value to use if a Character object in the collection is null * @return a char array containing the primitive char values from the specified range of the collection * @throws IndexOutOfBoundsException if the specified indices are out of the collection's range */ public static char[] toCharArray(final Collection c, final int fromIndex, final int toIndex, final char defaultForNull) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, size(c)); if (fromIndex == toIndex) { return EMPTY_CHAR_ARRAY; } final int len = toIndex - fromIndex; final char[] result = new char[len]; if (c instanceof final List list && c instanceof RandomAccess) { Character val = null; for (int i = 0; i < len; i++) { if ((val = list.get(i + fromIndex)) == null) { result[i] = defaultForNull; } else { result[i] = val; } } } else { final Iterator iter = c.iterator(); if (fromIndex > 0) { int offset = 0; while (offset++ < fromIndex) { iter.next(); } } Character val = null; for (int i = 0; i < len; i++) { if ((val = iter.next()) == null) { result[i] = defaultForNull; } else { result[i] = val; } } } return result; } /** * Converts a collection of Number objects to a byte array. * * @param c the collection of Number objects to be converted * @return a byte array containing the primitive byte values from the collection */ public static byte[] toByteArray(final Collection c) { return toByteArray(c, (byte) 0); } /** * Converts the specified range of the specified Number collection to a byte array. * * @param c the collection of Number objects to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return a byte array containing the primitive byte values from the specified range of the collection * @throws IndexOutOfBoundsException if the specified indices are out of the collection's range */ public static byte[] toByteArray(final Collection c, final int fromIndex, final int toIndex) { return toByteArray(c, fromIndex, toIndex, (byte) 0); } /** * Converts a collection of Number objects to a byte array. * * @param c the collection of Number objects to be converted * @param defaultForNull the default byte value to use if a Number object in the collection is null * @return a byte array containing the primitive byte values from the collection */ public static byte[] toByteArray(final Collection c, final byte defaultForNull) { return toByteArray(c, 0, size(c), defaultForNull); } /** * Converts the specified range of the specified Number collection to a byte array. * * @param c the collection of Number objects to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @param defaultForNull the default byte value to use if a Number object in the collection is null * @return a byte array containing the primitive byte values from the specified range of the collection * @throws IndexOutOfBoundsException if the specified indices are out of the collection's range */ public static byte[] toByteArray(final Collection c, final int fromIndex, final int toIndex, final byte defaultForNull) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, size(c)); if (fromIndex == toIndex) { return EMPTY_BYTE_ARRAY; } final int len = toIndex - fromIndex; final byte[] result = new byte[len]; if (c instanceof final List list && c instanceof RandomAccess) { Number val = null; for (int i = 0; i < len; i++) { if ((val = list.get(i + fromIndex)) == null) { result[i] = defaultForNull; } else { result[i] = val.byteValue(); } } } else { final Iterator iter = c.iterator(); if (fromIndex > 0) { int offset = 0; while (offset++ < fromIndex) { iter.next(); } } Number val = null; for (int i = 0; i < len; i++) { if ((val = iter.next()) == null) { result[i] = defaultForNull; } else { result[i] = val.byteValue(); } } } return result; } /** * Converts a boolean array to a byte array. * Each boolean value is converted to a byte value: {@code true} to 1 and {@code false} to 0. * * @param a the boolean array to be converted * @return a byte array with the same length as the input array, or an empty byte array if the input array is {@code null} or empty */ public static byte[] toByteArray(final boolean[] a) { if ((a == null) || (a.length == 0)) { return EMPTY_BYTE_ARRAY; // return null; // NOSONAR } else { final int len = a.length; final byte[] result = new byte[len]; for (int i = 0; i < len; i++) { result[i] = a[i] ? Numbers.BYTE_ONE : Numbers.BYTE_ZERO; } return result; } } /** * Converts a collection of Number objects to a short array. * * @param c the collection of Number objects to be converted * @return a short array containing the primitive short values from the collection */ public static short[] toShortArray(final Collection c) { return toShortArray(c, (short) 0); } /** * Converts the specified range of the specified Number collection to a short array. * * @param c the collection of Number objects to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return a short array containing the primitive short values from the specified range of the collection * @throws IndexOutOfBoundsException if the specified indices are out of the collection's range */ public static short[] toShortArray(final Collection c, final int fromIndex, final int toIndex) { return toShortArray(c, fromIndex, toIndex, (short) 0); } /** * Converts a collection of Number objects to a short array. * * @param c the collection of Number objects to be converted * @param defaultForNull the default short value to use if a Number object in the collection is null * @return a short array containing the primitive short values from the collection */ public static short[] toShortArray(final Collection c, final short defaultForNull) { return toShortArray(c, 0, size(c), defaultForNull); } /** * Converts the specified range of the specified Number collection to a short array. * * @param c the collection of Number objects to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @param defaultForNull the default short value to use if a Number object in the collection is null * @return a short array containing the primitive short values from the specified range of the collection * @throws IndexOutOfBoundsException if the specified indices are out of the collection's range */ public static short[] toShortArray(final Collection c, final int fromIndex, final int toIndex, final short defaultForNull) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, size(c)); if (fromIndex == toIndex) { return EMPTY_SHORT_ARRAY; } final int len = toIndex - fromIndex; final short[] result = new short[len]; if (c instanceof final List list && c instanceof RandomAccess) { Number val = null; for (int i = 0; i < len; i++) { if ((val = list.get(i + fromIndex)) == null) { result[i] = defaultForNull; } else { result[i] = val.shortValue(); } } } else { final Iterator iter = c.iterator(); if (fromIndex > 0) { int offset = 0; while (offset++ < fromIndex) { iter.next(); } } Number val = null; for (int i = 0; i < len; i++) { if ((val = iter.next()) == null) { result[i] = defaultForNull; } else { result[i] = val.shortValue(); } } } return result; } /** * Converts a collection of Number objects to an int array. * * @param c the collection of Number objects to be converted * @return an int array containing the primitive int values from the collection */ public static int[] toIntArray(final Collection c) { return toIntArray(c, 0); } /** * Converts the specified range of the specified Number collection to an int array. * * @param c the collection of Number objects to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return an int array containing the primitive int values from the specified range of the collection * @throws IndexOutOfBoundsException if the specified indices are out of the collection's range */ public static int[] toIntArray(final Collection c, final int fromIndex, final int toIndex) { return toIntArray(c, fromIndex, toIndex, 0); } /** * Converts a collection of Number objects to an int array. * * @param c the collection of Number objects to be converted * @param defaultForNull the default int value to use if a Number object in the collection is null * @return an int array containing the primitive int values from the collection */ public static int[] toIntArray(final Collection c, final int defaultForNull) { return toIntArray(c, 0, size(c), defaultForNull); } /** * Converts the specified range of the specified Number collection to an int array. * * @param c the collection of Number objects to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @param defaultForNull the default int value to use if a Number object in the collection is null * @return an int array containing the primitive int values from the specified range of the collection * @throws IndexOutOfBoundsException if the specified indices are out of the collection's range */ public static int[] toIntArray(final Collection c, final int fromIndex, final int toIndex, final int defaultForNull) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, size(c)); if (fromIndex == toIndex) { return EMPTY_INT_ARRAY; } final int len = toIndex - fromIndex; final int[] result = new int[len]; if (c instanceof final List list && c instanceof RandomAccess) { Number val = null; for (int i = 0; i < len; i++) { if ((val = list.get(i + fromIndex)) == null) { result[i] = defaultForNull; } else { result[i] = val.intValue(); } } } else { final Iterator iter = c.iterator(); if (fromIndex > 0) { int offset = 0; while (offset++ < fromIndex) { iter.next(); } } Number val = null; for (int i = 0; i < len; i++) { if ((val = iter.next()) == null) { result[i] = defaultForNull; } else { result[i] = val.intValue(); } } } return result; } /** * Converts a char array to an int array. * Each char value is converted to its corresponding int value. * * @param a the char array to be converted * @return an int array with the same length as the input array, or an empty byte array if the input array is {@code null} or empty */ public static int[] toIntArray(final char[] a) { if ((a == null) || (a.length == 0)) { return EMPTY_INT_ARRAY; // return null; // NOSONAR } else { final int len = a.length; final int[] result = new int[len]; for (int i = 0; i < len; i++) { result[i] = a[i]; //NOSONAR } return result; } } /** * Converts a boolean array to an int array. * Each boolean value is converted to an int value: {@code true} to 1 and {@code false} to 0. * * @param a the boolean array to be converted * @return an int array with the same length as the input array, or an empty byte array if the input array is {@code null} or empty */ public static int[] toIntArray(final boolean[] a) { if ((a == null) || (a.length == 0)) { return EMPTY_INT_ARRAY; // return null; // NOSONAR } else { final int len = a.length; final int[] result = new int[len]; for (int i = 0; i < len; i++) { result[i] = a[i] ? 1 : 0; } return result; } } /** * Converts a collection of Number objects to a long array. * * @param c the collection of Number objects to be converted * @return a long array containing the primitive long values from the collection */ public static long[] toLongArray(final Collection c) { return toLongArray(c, 0); } /** * Converts the specified range of the specified Number collection to a long array. * * @param c the collection of Number objects to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return a long array containing the primitive long values from the specified range of the collection * @throws IndexOutOfBoundsException if the specified indices are out of the collection's range */ public static long[] toLongArray(final Collection c, final int fromIndex, final int toIndex) { return toLongArray(c, fromIndex, toIndex, 0); } /** * Converts a collection of Number objects to a long array. * * @param c the collection of Number objects to be converted * @param defaultForNull the default long value to use if a Number object in the collection is null * @return a long array containing the primitive long values from the collection */ public static long[] toLongArray(final Collection c, final long defaultForNull) { return toLongArray(c, 0, size(c), defaultForNull); } /** * Converts the specified range of the specified Number collection to a long array. * * @param c the collection of Number objects to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @param defaultForNull the default long value to use if a Number object in the collection is null * @return a long array containing the primitive long values from the specified range of the collection * @throws IndexOutOfBoundsException if the specified indices are out of the collection's range */ public static long[] toLongArray(final Collection c, final int fromIndex, final int toIndex, final long defaultForNull) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, size(c)); if (fromIndex == toIndex) { return EMPTY_LONG_ARRAY; } final int len = toIndex - fromIndex; final long[] result = new long[len]; if (c instanceof final List list && c instanceof RandomAccess) { Number val = null; for (int i = 0; i < len; i++) { if ((val = list.get(i + fromIndex)) == null) { result[i] = defaultForNull; } else { result[i] = val.longValue(); } } } else { final Iterator iter = c.iterator(); if (fromIndex > 0) { int offset = 0; while (offset++ < fromIndex) { iter.next(); } } Number val = null; for (int i = 0; i < len; i++) { if ((val = iter.next()) == null) { result[i] = defaultForNull; } else { result[i] = val.longValue(); } } } return result; } /** * Converts a collection of Number objects to a float array. * * @param c the collection of Number objects to be converted * @return a float array containing the primitive float values from the collection */ public static float[] toFloatArray(final Collection c) { return toFloatArray(c, 0); } /** * Converts the specified range of the specified Number collection to a float array. * * @param c the collection of Number objects to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return a float array containing the primitive float values from the specified range of the collection * @throws IndexOutOfBoundsException if the specified indices are out of the collection's range */ public static float[] toFloatArray(final Collection c, final int fromIndex, final int toIndex) { return toFloatArray(c, fromIndex, toIndex, 0); } /** * Converts a collection of Number objects to a float array. * * @param c the collection of Number objects to be converted * @param defaultForNull the default float value to use if a Number object in the collection is null * @return a float array containing the primitive float values from the collection */ public static float[] toFloatArray(final Collection c, final float defaultForNull) { return toFloatArray(c, 0, size(c), defaultForNull); } /** * Converts the specified range of the specified Number collection to a float array. * * @param c the collection of Number objects to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @param defaultForNull the default float value to use if a Number object in the collection is null * @return a float array containing the primitive float values from the specified range of the collection * @throws IndexOutOfBoundsException if the specified indices are out of the collection's range */ public static float[] toFloatArray(final Collection c, final int fromIndex, final int toIndex, final float defaultForNull) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, size(c)); if (fromIndex == toIndex) { return EMPTY_FLOAT_ARRAY; } final int len = toIndex - fromIndex; final float[] result = new float[len]; if (c instanceof final List list && c instanceof RandomAccess) { Number val = null; for (int i = 0; i < len; i++) { if ((val = list.get(i + fromIndex)) == null) { result[i] = defaultForNull; } else { result[i] = Numbers.toFloat(val); } } } else { final Iterator iter = c.iterator(); if (fromIndex > 0) { int offset = 0; while (offset++ < fromIndex) { iter.next(); } } Number val = null; for (int i = 0; i < len; i++) { if ((val = iter.next()) == null) { result[i] = defaultForNull; } else { result[i] = Numbers.toFloat(val); } } } return result; } /** * Converts a collection of Number objects to a double array. * * @param c the collection of Number objects to be converted * @return a double array containing the primitive double values from the collection */ public static double[] toDoubleArray(final Collection c) { return toDoubleArray(c, 0); } /** * Converts the specified range of the specified Number collection to a double array. * * @param c the collection of Number objects to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return a double array containing the primitive double values from the specified range of the collection * @throws IndexOutOfBoundsException if the specified indices are out of the collection's range */ public static double[] toDoubleArray(final Collection c, final int fromIndex, final int toIndex) { return toDoubleArray(c, fromIndex, toIndex, 0); } /** * Converts a collection of Number objects to a double array. * * @param c the collection of Number objects to be converted * @param defaultForNull the default double value to use if a Number object in the collection is null * @return a double array containing the primitive double values from the collection */ public static double[] toDoubleArray(final Collection c, final double defaultForNull) { return toDoubleArray(c, 0, size(c), defaultForNull); } /** * Converts the specified range of the specified Number collection to a double array. * * @param c the collection of Number objects to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @param defaultForNull the default double value to use if a Number object in the collection is null * @return a double array containing the primitive double values from the specified range of the collection * @throws IndexOutOfBoundsException if the specified indices are out of the collection's range */ public static double[] toDoubleArray(final Collection c, final int fromIndex, final int toIndex, final double defaultForNull) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, size(c)); if (fromIndex == toIndex) { return EMPTY_DOUBLE_ARRAY; } final int len = toIndex - fromIndex; final double[] result = new double[len]; if (c instanceof final List list && c instanceof RandomAccess) { Number val = null; for (int i = 0; i < len; i++) { if ((val = list.get(i + fromIndex)) == null) { result[i] = defaultForNull; } else { result[i] = Numbers.toDouble(val); } } } else { final Iterator iter = c.iterator(); if (fromIndex > 0) { int offset = 0; while (offset++ < fromIndex) { iter.next(); } } Number val = null; for (int i = 0; i < len; i++) { if ((val = iter.next()) == null) { result[i] = defaultForNull; } else { result[i] = Numbers.toDouble(val); } } } return result; } /** * Converts a boolean array to a modifiable List, which is NOT backed with the input array * * @param a the boolean array to be converted * @return a modifiable List of Boolean objects containing the values from the boolean array */ public static List toList(final boolean[] a) { return toList(a, 0, len(a)); // NOSONAR } /** * Converts the specified range of the array to a modifiable List, which is NOT backed with the input array * * @param a the boolean array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return a modifiable List of Boolean objects containing the values from the specified range of the boolean array * @throws IndexOutOfBoundsException if the specified indices are out of the array's range */ public static List toList(final boolean[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return new ArrayList<>(); } final List result = new ArrayList<>(toIndex - fromIndex); for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); } return result; } /** * Converts a char array to a modifiable List, which is NOT backed with the input array * * @param a the char array to be converted * @return a modifiable List of Character objects containing the values from the char array */ public static List toList(final char[] a) { return toList(a, 0, len(a)); // NOSONAR } /** * Converts the specified range of the array to a modifiable List, which is NOT backed with the input array * * @param a the char array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return a modifiable List of Character objects containing the values from the specified range of the char array * @throws IndexOutOfBoundsException if the specified indices are out of the array's range */ public static List toList(final char[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return new ArrayList<>(); } final List result = new ArrayList<>(toIndex - fromIndex); for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); } return result; } /** * Converts a byte array to a modifiable List, which is NOT backed with the input array * * @param a the byte array to be converted * @return a modifiable List of Byte objects containing the values from the byte array */ public static List toList(final byte[] a) { return toList(a, 0, len(a)); // NOSONAR } /** * Converts the specified range of the byte array to a modifiable List, which is NOT backed with the input array * * @param a the byte array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return a modifiable List of Byte objects containing the values from the specified range of the byte array * @throws IndexOutOfBoundsException if the specified indices are out of the array's range */ public static List toList(final byte[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return new ArrayList<>(); } final List result = new ArrayList<>(toIndex - fromIndex); for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); } return result; } /** * Converts a short array to a modifiable List, which is NOT backed with the input array * * @param a the short array to be converted * @return a modifiable List of Short objects containing the values from the short array */ public static List toList(final short[] a) { return toList(a, 0, len(a)); // NOSONAR } /** * Converts the specified range of the short array to a modifiable List, which is NOT backed with the input array * * @param a the short array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return a modifiable List of Short objects containing the values from the specified range of the short array * @throws IndexOutOfBoundsException if the specified indices are out of the array's range */ public static List toList(final short[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return new ArrayList<>(); } final List result = new ArrayList<>(toIndex - fromIndex); for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); } return result; } /** * Converts an int array to a modifiable List, which is NOT backed with the input array * * @param a the int array to be converted * @return a modifiable List of Integer objects containing the values from the int array */ public static List toList(final int[] a) { return toList(a, 0, len(a)); // NOSONAR } /** * Converts the specified range of the int array to a modifiable List, which is NOT backed with the input array * * @param a the int array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return a modifiable List of Integer objects containing the values from the specified range of the int array * @throws IndexOutOfBoundsException if the specified indices are out of the array's range */ public static List toList(final int[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return new ArrayList<>(); } final List result = new ArrayList<>(toIndex - fromIndex); for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); } return result; } /** * Converts a long array to a modifiable List, which is NOT backed with the input array * * @param a the long array to be converted * @return a modifiable List of Long objects containing the values from the long array */ public static List toList(final long[] a) { return toList(a, 0, len(a)); // NOSONAR } /** * Converts the specified range of the long array to a modifiable List, which is NOT backed with the input array * * @param a the long array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return a modifiable List of Long objects containing the values from the specified range of the long array * @throws IndexOutOfBoundsException if the specified indices are out of the array's range */ public static List toList(final long[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return new ArrayList<>(); } final List result = new ArrayList<>(toIndex - fromIndex); for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); } return result; } /** * Converts a float array to a modifiable List, which is NOT backed with the input array * * @param a the float array to be converted * @return a modifiable List of Float objects containing the values from the float array */ public static List toList(final float[] a) { return toList(a, 0, len(a)); // NOSONAR } /** * Converts the specified range of the float array to a modifiable List, which is NOT backed with the input array * * @param a the float array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return a modifiable List of Float objects containing the values from the specified range of the float array * @throws IndexOutOfBoundsException if the specified indices are out of the array's range */ public static List toList(final float[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return new ArrayList<>(); } final List result = new ArrayList<>(toIndex - fromIndex); for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); } return result; } /** * Converts a double array to a modifiable List, which is NOT backed with the input array * * @param a the double array to be converted * @return a modifiable List of Double objects containing the values from the double array */ public static List toList(final double[] a) { return toList(a, 0, len(a)); // NOSONAR } /** * Converts the specified range of the double array to a modifiable List, which is NOT backed with the input array * * @param a the double array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return a modifiable List of Double objects containing the values from the specified range of the double array * @throws IndexOutOfBoundsException if the specified indices are out of the array's range */ public static List toList(final double[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return new ArrayList<>(); } final List result = new ArrayList<>(toIndex - fromIndex); for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); } return result; } /** * Converts an array of objects to a modifiable List, which is NOT backed with the input array. * * @param the type of elements in the array * @param a the array to be converted * @return a modifiable List of objects containing the values from the array */ public static List toList(final T[] a) { if (isEmpty(a)) { return new ArrayList<>(); } return asList(a); } /** * Converts the specified range of the array to a modifiable List, which is NOT backed with the input array. * * @param the type of elements in the array * @param a the array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return a modifiable List of objects containing the values from the specified range of the array * @throws IndexOutOfBoundsException if the specified indices are out of the array's range */ public static List toList(final T[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return new ArrayList<>(); } else if (fromIndex == 0 && toIndex == a.length) { return asList(a); } final List result = new ArrayList<>(toIndex - fromIndex); //noinspection ManualArrayToCollectionCopy for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); //NOSONAR } return result; } /** * Converts an Iterator of objects to a modifiable List. * * @param the type of elements in the iterator * @param iter the iterator to be converted * @return a modifiable List of objects containing the values from the iterator */ public static List toList(final Iterator iter) { if (iter == null) { return new ArrayList<>(); } final List result = new ArrayList<>(); while (iter.hasNext()) { result.add(iter.next()); } return result; } /** * Converts a boolean array to a modifiable Set, which is NOT backed with the input array. * * @param a the boolean array to be converted * @return a modifiable Set of Boolean objects containing the values from the boolean array */ public static Set toSet(final boolean[] a) { return toSet(a, 0, len(a)); // NOSONAR } /** * Converts the specified range of the boolean array to a modifiable Set, which is NOT backed with the input array. * * @param a the boolean array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return a modifiable Set of Boolean objects containing the values from the specified range of the boolean array * @throws IndexOutOfBoundsException if the specified indices are out of the array's range */ public static Set toSet(final boolean[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return newHashSet(); } final Set result = newHashSet(toIndex - fromIndex); for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); } return result; } /** * Converts a char array to a modifiable Set, which is NOT backed with the input array. * * @param a the char array to be converted * @return a modifiable Set of Character objects containing the values from the char array */ public static Set toSet(final char[] a) { return toSet(a, 0, len(a)); // NOSONAR } /** * Converts the specified range of the char array to a modifiable Set, which is NOT backed with the input array. * * @param a the char array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return a modifiable Set of Character objects containing the values from the specified range of the char array * @throws IndexOutOfBoundsException if the specified indices are out of the array's range */ public static Set toSet(final char[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return newHashSet(); } final Set result = newHashSet(toIndex - fromIndex); for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); } return result; } /** * Converts a byte array to a modifiable Set, which is NOT backed with the input array. * * @param a the byte array to be converted * @return a modifiable Set of Byte objects containing the values from the byte array */ public static Set toSet(final byte[] a) { return toSet(a, 0, len(a)); // NOSONAR } /** * Converts the specified range of the byte array to a modifiable Set, which is NOT backed with the input array. * * @param a the byte array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return a modifiable Set of Byte objects containing the values from the specified range of the byte array * @throws IndexOutOfBoundsException if the specified indices are out of the array's range */ public static Set toSet(final byte[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return newHashSet(); } final Set result = newHashSet(toIndex - fromIndex); for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); } return result; } /** * Converts a short array to a modifiable Set, which is NOT backed with the input array. * * @param a the short array to be converted * @return a modifiable Set of Short objects containing the values from the short array */ public static Set toSet(final short[] a) { return toSet(a, 0, len(a)); // NOSONAR } /** * Converts the specified range of the short array to a modifiable Set, which is NOT backed with the input array. * * @param a the short array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return a modifiable Set of Short objects containing the values from the specified range of the short array * @throws IndexOutOfBoundsException if the specified indices are out of the array's range */ public static Set toSet(final short[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return newHashSet(); } final Set result = newHashSet(toIndex - fromIndex); for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); } return result; } /** * Converts an int array to a modifiable Set, which is NOT backed with the input array. * * @param a the int array to be converted * @return a modifiable Set of Integer objects containing the values from the int array */ public static Set toSet(final int[] a) { return toSet(a, 0, len(a)); // NOSONAR } /** * Converts the specified range of the int array to a modifiable Set, which is NOT backed with the input array. * * @param a the int array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return a modifiable Set of Integer objects containing the values from the specified range of the int array * @throws IndexOutOfBoundsException if the specified indices are out of the array's range */ public static Set toSet(final int[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return newHashSet(); } final Set result = newHashSet(toIndex - fromIndex); for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); } return result; } /** * Converts a long array to a modifiable Set, which is NOT backed with the input array. * * @param a the long array to be converted * @return a modifiable Set of Long objects containing the values from the long array */ public static Set toSet(final long[] a) { return toSet(a, 0, len(a)); // NOSONAR } /** * Converts the specified range of the long array to a modifiable Set, which is NOT backed with the input array. * * @param a the long array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return a modifiable Set of Long objects containing the values from the specified range of the long array * @throws IndexOutOfBoundsException if the specified indices are out of the array's range */ public static Set toSet(final long[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return newHashSet(); } final Set result = newHashSet(toIndex - fromIndex); for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); } return result; } /** * Converts a float array to a Set of, which is NOT backed with the input array. * * @param a the float array to be converted * @return a modifiable Set of Float objects containing the values from the float array */ public static Set toSet(final float[] a) { return toSet(a, 0, len(a)); // NOSONAR } /** * Converts the specified range of the float array to a modifiable Set, which is NOT backed with the input array. * * @param a the float array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return a modifiable Set of Float objects containing the values from the specified range of the float array * @throws IndexOutOfBoundsException if the specified indices are out of the array's range */ public static Set toSet(final float[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return newHashSet(); } final Set result = newHashSet(toIndex - fromIndex); for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); } return result; } /** * Converts a double array to a modifiable Set, which is NOT backed with the input array. * * @param a the double array to be converted * @return a modifiable Set of Double objects containing the values from the double array */ public static Set toSet(final double[] a) { return toSet(a, 0, len(a)); // NOSONAR } /** * Converts the specified range of the double array to a modifiable Set, which is NOT backed with the input array. * * @param a the double array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return a modifiable Set of Double objects containing the values from the specified range of the double array * @throws IndexOutOfBoundsException if the specified indices are out of the array's range */ public static Set toSet(final double[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return newHashSet(); } final Set result = newHashSet(toIndex - fromIndex); for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); } return result; } /** * Converts an array of objects to a modifiable Set, which is NOT backed with the input array. * * @param the type of elements in the array * @param a the array to be converted * @return a modifiable Set of objects containing the values from the array */ public static Set toSet(final T[] a) { if (isEmpty(a)) { return newHashSet(); } return asSet(a); } /** * Converts the specified range of the array to a modifiable Set, which is NOT backed with the input array. * * @param the type of elements in the array * @param a the array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @return a modifiable Set of objects containing the values from the specified range of the array * @throws IndexOutOfBoundsException if the specified indices are out of the array's range */ public static Set toSet(final T[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return newHashSet(); } final Set result = newHashSet(toIndex - fromIndex); //noinspection ManualArrayToCollectionCopy for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); //NOSONAR } return result; } /** * Converts an Iterator of objects to a modifiable Set. * * @param the type of elements in the iterator * @param iter the iterator to be converted * @return a modifiable Set of objects containing the values from the iterator */ public static Set toSet(final Iterator iter) { if (iter == null) { return newHashSet(); } final Set result = newHashSet(); while (iter.hasNext()) { result.add(iter.next()); } return result; } /** * Converts a boolean array to a specified type of Collection. * * @param the type of Collection to be returned * @param a the boolean array to be converted * @param supplier a function that provides a new instance of the desired Collection type * @return a Collection of Boolean objects containing the values from the boolean array * @see IntFunctions#ofList() * @see IntFunctions#ofSet() */ public static > C toCollection(final boolean[] a, final IntFunction supplier) { return toCollection(a, 0, len(a), supplier); } /** * Converts the specified range of the boolean array to a specified type of Collection. * * @param the type of Collection to be returned * @param a the boolean array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @param supplier a function that provides a new instance of the desired Collection type * @return a Collection of Boolean objects containing the values from the specified range of the boolean array * @throws IndexOutOfBoundsException if the specified indices are out of the array's range * @see IntFunctions#ofList() * @see IntFunctions#ofSet() */ public static > C toCollection(final boolean[] a, final int fromIndex, final int toIndex, final IntFunction supplier) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return supplier.apply(0); } final C result = supplier.apply(toIndex - fromIndex); for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); } return result; } /** * Converts a char array to a specified type of Collection. * * @param the type of Collection to be returned * @param a the char array to be converted * @param supplier a function that provides a new instance of the desired Collection type * @return a Collection of Character objects containing the values from the char array * @see IntFunctions#ofList() * @see IntFunctions#ofSet() */ public static > C toCollection(final char[] a, final IntFunction supplier) { return toCollection(a, 0, len(a), supplier); } /** * Converts the specified range of the char array to a specified type of Collection. * * @param the type of Collection to be returned * @param a the char array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @param supplier a function that provides a new instance of the desired Collection type * @return a Collection of Character objects containing the values from the specified range of the char array * @throws IndexOutOfBoundsException if the specified indices are out of the array's range * @see IntFunctions#ofList() * @see IntFunctions#ofSet() */ public static > C toCollection(final char[] a, final int fromIndex, final int toIndex, final IntFunction supplier) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return supplier.apply(0); } final C result = supplier.apply(toIndex - fromIndex); for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); } return result; } /** * Converts a byte array to a specified type of Collection. * * @param the type of Collection to be returned * @param a the byte array to be converted * @param supplier a function that provides a new instance of the desired Collection type * @return a Collection of Byte objects containing the values from the byte array * @see IntFunctions#ofList() * @see IntFunctions#ofSet() */ public static > C toCollection(final byte[] a, final IntFunction supplier) { return toCollection(a, 0, len(a), supplier); } /** * Converts the specified range of the byte array to a specified type of Collection. * * @param the type of Collection to be returned * @param a the byte array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @param supplier a function that provides a new instance of the desired Collection type * @return a Collection of Byte objects containing the values from the specified range of the byte array * @throws IndexOutOfBoundsException if the specified indices are out of the array's range * @see IntFunctions#ofList() * @see IntFunctions#ofSet() */ public static > C toCollection(final byte[] a, final int fromIndex, final int toIndex, final IntFunction supplier) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return supplier.apply(0); } final C result = supplier.apply(toIndex - fromIndex); for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); } return result; } /** * Converts a short array to a specified type of Collection. * * @param the type of Collection to be returned * @param a the short array to be converted * @param supplier a function that provides a new instance of the desired Collection type * @return a Collection of Short objects containing the values from the short * @see IntFunctions#ofList() * @see IntFunctions#ofSet() */ public static > C toCollection(final short[] a, final IntFunction supplier) { return toCollection(a, 0, len(a), supplier); } /** * Converts the specified range of the short array to a specified type of Collection. * * @param the type of Collection to be returned * @param a the short array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @param supplier a function that provides a new instance of the desired Collection type * @return a Collection of Short objects containing the values from the specified range of the short array * @throws IndexOutOfBoundsException if the specified indices are out of the array's * @see IntFunctions#ofList() * @see IntFunctions#ofSet() */ public static > C toCollection(final short[] a, final int fromIndex, final int toIndex, final IntFunction supplier) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return supplier.apply(0); } final C result = supplier.apply(toIndex - fromIndex); for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); } return result; } /** * Converts an int array to a specified type of Collection. * * @param the type of Collection to be returned * @param a the int array to be converted * @param supplier a function that provides a new instance of the desired Collection type * @return a Collection of Integer objects containing the values from the int array * @see IntFunctions#ofList() * @see IntFunctions#ofSet() */ public static > C toCollection(final int[] a, final IntFunction supplier) { return toCollection(a, 0, len(a), supplier); } /** * Converts the specified range of the int array to a specified type of Collection. * * @param the type of Collection to be returned * @param a the int array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @param supplier a function that provides a new instance of the desired Collection type * @return a Collection of Integer objects containing the values from the specified range of the int array * @throws IndexOutOfBoundsException if the specified indices are out of the array's range * @see IntFunctions#ofList() * @see IntFunctions#ofSet() */ public static > C toCollection(final int[] a, final int fromIndex, final int toIndex, final IntFunction supplier) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return supplier.apply(0); } final C result = supplier.apply(toIndex - fromIndex); for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); } return result; } /** * Converts a long array to a specified type of Collection. * * @param the type of Collection to be returned * @param a the long array to be converted * @param supplier a function that provides a new instance of the desired Collection type * @return a Collection of Long objects containing the values from the long array * @see IntFunctions#ofList() * @see IntFunctions#ofSet() */ public static > C toCollection(final long[] a, final IntFunction supplier) { return toCollection(a, 0, len(a), supplier); } /** * Converts the specified range of the long array to a specified type of Collection. * * @param the type of Collection to be returned * @param a the long array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @param supplier a function that provides a new instance of the desired Collection type * @return a Collection of Long objects containing the values from the specified range of the long array * @throws IndexOutOfBoundsException if the specified indices are out of the array's * @see IntFunctions#ofList() * @see IntFunctions#ofSet() */ public static > C toCollection(final long[] a, final int fromIndex, final int toIndex, final IntFunction supplier) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return supplier.apply(0); } final C result = supplier.apply(toIndex - fromIndex); for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); } return result; } /** * Converts a float array to a specified type of Collection. * * @param the type of Collection to be returned * @param a the float array to be converted * @param supplier a function that provides a new instance of the desired Collection type * @return a Collection of Float objects containing the values from the float array * @see IntFunctions#ofList() * @see IntFunctions#ofSet() */ public static > C toCollection(final float[] a, final IntFunction supplier) { return toCollection(a, 0, len(a), supplier); } /** * Converts the specified range of the float array to a specified type of Collection. * * @param the type of Collection to be returned * @param a the float array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @param supplier a function that provides a new instance of the desired Collection type * @return a Collection of Float objects containing the values from the specified range of the float array * @throws IndexOutOfBoundsException if the specified indices are out of the array's range * @see IntFunctions#ofList() * @see IntFunctions#ofSet() */ public static > C toCollection(final float[] a, final int fromIndex, final int toIndex, final IntFunction supplier) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return supplier.apply(0); } final C result = supplier.apply(toIndex - fromIndex); for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); } return result; } /** * Converts a double array to a specified type of Collection. * * @param the type of Collection to be returned * @param a the double array to be converted * @param supplier a function that provides a new instance of the desired Collection type * @return a Collection of Double objects containing the values from the double array * @see IntFunctions#ofList() * @see IntFunctions#ofSet() */ public static > C toCollection(final double[] a, final IntFunction supplier) { return toCollection(a, 0, len(a), supplier); } /** * Converts the specified range of the double array to a specified type of Collection. * * @param the type of Collection to be returned * @param a the double array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @param supplier a function that provides a new instance of the desired Collection type * @return a Collection of Double objects containing the values from the specified range of the double array * @throws IndexOutOfBoundsException if the specified indices are out of the array's range * @see IntFunctions#ofList() * @see IntFunctions#ofSet() */ public static > C toCollection(final double[] a, final int fromIndex, final int toIndex, final IntFunction supplier) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return supplier.apply(0); } final C result = supplier.apply(toIndex - fromIndex); for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); } return result; } /** * Converts an array of objects to a specified type of Collection. * * @param the type of elements in the array and the Collection * @param the type of Collection to be returned * @param a the array to be converted * @param supplier a function that provides a new instance of the desired Collection type * @return a Collection of objects containing the values from the array * @see IntFunctions#ofList() * @see IntFunctions#ofSet() */ public static > C toCollection(final T[] a, final IntFunction supplier) { if (isEmpty(a)) { return supplier.apply(0); } return toCollection(a, 0, a.length, supplier); } /** * Converts the specified range of the array to a specified type of Collection. * * @param the type of elements in the array and the Collection * @param the type of Collection to be returned * @param a the array to be converted * @param fromIndex the starting (inclusive) index of the range to be converted * @param toIndex the ending (exclusive) index of the range to be converted * @param supplier a function that provides a new instance of the desired Collection type * @return a Collection of objects containing the values from the specified range of the array * @throws IndexOutOfBoundsException if the specified indices are out of the array's range * @see IntFunctions#ofList() * @see IntFunctions#ofSet() */ public static > C toCollection(final T[] a, final int fromIndex, final int toIndex, final IntFunction supplier) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return supplier.apply(0); } else if (fromIndex == 0 && toIndex == a.length && a.length >= MIN_SIZE_FOR_COPY_ALL) { final C result = supplier.apply(a.length); result.addAll(Array.asList(a)); return result; } else { final C result = supplier.apply(toIndex - fromIndex); //noinspection ManualArrayToCollectionCopy for (int i = fromIndex; i < toIndex; i++) { result.add(a[i]); //NOSONAR } return result; } } /** * Converts an Iterable to a specified type of Collection. * * @param the type of elements in the Iterable and the Collection * @param the type of Collection to be returned * @param c the Iterable to be converted * @param supplier a function that provides a new instance of the desired Collection type * @return a Collection of objects containing the values from the Iterable * @see IntFunctions#ofList() * @see IntFunctions#ofSet() */ public static > C toCollection(final Iterable c, final IntFunction supplier) { if (isEmptyCollection(c)) { return supplier.apply(0); } if (c instanceof Collection) { final Collection tmp = (Collection) c; final C ret = supplier.apply(tmp.size()); ret.addAll(tmp); return ret; } else { final Iterator iter = c.iterator(); final C ret = supplier.apply(0); while (iter.hasNext()) { ret.add(iter.next()); } return ret; } } /** * Converts an Iterator to a specified type of Collection. * * @param the type of elements in the Iterator and the Collection * @param the type of Collection to be returned * @param iter the Iterator to be converted * @param supplier a function that provides a new instance of the desired Collection type * @return a Collection of objects containing the values from the Iterator * @see IntFunctions#ofList() * @see IntFunctions#ofSet() */ public static > C toCollection(final Iterator iter, final Supplier supplier) { final C c = supplier.get(); if (iter == null) { return c; } while (iter.hasNext()) { c.add(iter.next()); } return c; } /** * Converts an Iterable to a Map using a key extractor function. * * @param the type of elements in the Iterable * @param the type of keys in the resulting Map * @param c the Iterable to be converted * @param keyExtractor a function that extracts keys from the elements of the Iterable * @return a Map containing the elements of the Iterable, with keys extracted by the keyExtractor function */ public static Map toMap(final Iterable c, final Function keyExtractor) { if (isEmptyCollection(c)) { return new HashMap<>(0); } final Map result = newHashMap(c instanceof Collection ? ((Collection) c).size() : 0); for (final T e : c) { result.put(keyExtractor.apply(e), e); } return result; } /** * Converts an Iterable to a Map using key and value extractor functions. * * @param the type of elements in the Iterable * @param the type of keys in the resulting Map * @param the type of values in the resulting Map * @param c the Iterable to be converted * @param keyExtractor a function that extracts keys from the elements of the Iterable * @param valueExtractor a function that extracts values from the elements of the Iterable * @return a Map containing the elements of the Iterable, with keys and values extracted by the keyExtractor and valueExtractor functions */ public static Map toMap(final Iterable c, final Function keyExtractor, final Function valueExtractor) { if (isEmptyCollection(c)) { return new HashMap<>(0); } final Map result = newHashMap(c instanceof Collection ? ((Collection) c).size() : 0); for (final T e : c) { result.put(keyExtractor.apply(e), valueExtractor.apply(e)); } return result; } /** * Converts an Iterable to a Map using key and value extractor functions, with a custom Map supplier. * * @param the type of elements in the Iterable * @param the type of keys in the resulting Map * @param the type of values in the resulting Map * @param the type of Map to be returned * @param c the Iterable to be converted * @param keyExtractor a function that extracts keys from the elements of the Iterable * @param valueExtractor a function that extracts values from the elements of the Iterable * @param mapSupplier a function that provides a new instance of the desired Map type * @return a Map containing the elements of the Iterable, with keys and values extracted by the keyExtractor and valueExtractor functions */ public static > M toMap(final Iterable c, final Function keyExtractor, final Function valueExtractor, final IntFunction mapSupplier) { if (isEmptyCollection(c)) { return mapSupplier.apply(0); } final M result = mapSupplier.apply(c instanceof Collection ? ((Collection) c).size() : 0); for (final T e : c) { result.put(keyExtractor.apply(e), valueExtractor.apply(e)); } return result; } /** * Converts an Iterable to a Map using key and value extractor functions, with a custom Map supplier. * * @param the type of elements in the Iterable * @param the type of keys in the resulting Map * @param the type of values in the resulting Map * @param the type of Map to be returned * @param c the Iterable to be converted * @param keyExtractor a function that extracts keys from the elements of the Iterable * @param valueExtractor a function that extracts values from the elements of the Iterable * @param mapSupplier a function that provides a new instance of the desired Map type * @return a Map containing the elements of the Iterable, with keys and values extracted by the keyExtractor and valueExtractor functions */ public static > M toMap(final Iterable c, final Function keyExtractor, final Function valueExtractor, final BiFunction mergeFunction, final IntFunction mapSupplier) { if (isEmptyCollection(c)) { return mapSupplier.apply(0); } final M result = mapSupplier.apply(c instanceof Collection ? ((Collection) c).size() : 0); K key = null; for (final T e : c) { key = keyExtractor.apply(e); final V oldValue = result.get(key); if (oldValue == null && !result.containsKey(key)) { result.put(key, valueExtractor.apply(e)); } else { result.put(key, mergeFunction.apply(oldValue, valueExtractor.apply(e))); } } return result; } /** * Converts an Iterator to a Map using a key extractor function. * * @param the type of elements in the Iterator * @param the type of keys in the resulting Map * @param iter the Iterator to be converted * @param keyExtractor a function that extracts keys from the elements of the Iterator * @return a Map containing the elements of the Iterator, with keys extracted by the keyExtractor function */ public static Map toMap(final Iterator iter, final Function keyExtractor) { if (iter == null) { return new HashMap<>(); } final Map result = new HashMap<>(); T e = null; while (iter.hasNext()) { e = iter.next(); result.put(keyExtractor.apply(e), e); } return result; } /** * Converts an Iterator to a Map using key and value extractor functions. * * @param the type of elements in the Iterator * @param the type of keys in the resulting Map * @param the type of values in the resulting Map * @param iter the Iterator to be converted * @param keyExtractor a function that extracts keys from the elements of the Iterator * @param valueExtractor a function that extracts values from the elements of the Iterator * @return a Map containing the elements of the Iterator, with keys and values extracted by the keyExtractor and valueExtractor functions */ public static Map toMap(final Iterator iter, final Function keyExtractor, final Function valueExtractor) { if (iter == null) { return new HashMap<>(); } final Map result = new HashMap<>(); T e = null; while (iter.hasNext()) { e = iter.next(); result.put(keyExtractor.apply(e), valueExtractor.apply(e)); } return result; } /** * Converts an Iterator to a Map using key and value extractor functions, with a custom Map supplier. * * @param the type of elements in the Iterator * @param the type of keys in the resulting Map * @param the type of values in the resulting Map * @param the type of Map to be returned * @param iter the Iterator to be converted * @param keyExtractor a function that extracts keys from the elements of the Iterator * @param valueExtractor a function that extracts values from the elements of the Iterator * @param mapSupplier a function that provides a new instance of the desired Map type * @return a Map containing the elements of the Iterator, with keys and values extracted by the keyExtractor and valueExtractor functions */ public static > M toMap(final Iterator iter, final Function keyExtractor, final Function valueExtractor, final Supplier mapSupplier) { if (iter == null) { return mapSupplier.get(); } final M result = mapSupplier.get(); T e = null; while (iter.hasNext()) { e = iter.next(); result.put(keyExtractor.apply(e), valueExtractor.apply(e)); } return result; } /** * Converts an Iterator to a Map using key and value extractor functions, with a custom Map supplier. * * @param the type of elements in the Iterator * @param the type of keys in the resulting Map * @param the type of values in the resulting Map * @param the type of Map to be returned * @param iter the Iterator to be converted * @param keyExtractor a function that extracts keys from the elements of the Iterator * @param valueExtractor a function that extracts values from the elements of the Iterator * @param mergeFunction a function that merges values if the same key is encountered * @param mapSupplier a function that provides a new instance of the desired Map type * @return a Map containing the elements of the Iterator, with keys and values extracted by the keyExtractor and valueExtractor functions */ public static > M toMap(final Iterator iter, final Function keyExtractor, final Function valueExtractor, final BiFunction mergeFunction, final Supplier mapSupplier) { if (iter == null) { return mapSupplier.get(); } final M result = mapSupplier.get(); T e = null; K key = null; while (iter.hasNext()) { e = iter.next(); key = keyExtractor.apply(e); final V oldValue = result.get(key); if (oldValue == null && !result.containsKey(key)) { result.put(key, valueExtractor.apply(e)); } else { result.put(key, mergeFunction.apply(oldValue, valueExtractor.apply(e))); } } return result; } /** * Returns the input array as is. * * @param the type of the array elements * @param a the input array * @return the input array */ @SafeVarargs public static T[] asArray(final T... a) { return a; } /** * Creates a new Map by populating it with the provided key-value pairs or another Map. * * @param the type of keys in the Map * @param the type of values in the Map * @param the type of Map to be returned * @param m the Map to be populated * @param a an array of key-value pairs or a single Map to populate the Map * @return the populated Map */ @SuppressWarnings("unchecked") static > T newMap(final T m, final Object... a) { if (isEmpty(a)) { return m; } if (a.length == 1) { if (a[0] instanceof Map) { m.putAll((Map) a[0]); } else if (ClassUtil.isBeanClass(a[0].getClass())) { Maps.bean2Map(a[0], (Map) m); } else { throw new IllegalArgumentException( "The parameters must be the pairs of property name and value, or Map, or a bean class with getter/setter methods."); } } else { if (0 != (a.length % 2)) { throw new IllegalArgumentException( "The parameters must be the pairs of property name and value, or Map, or a bean class with getter/setter methods."); } for (int i = 0; i < a.length; i++) { m.put((K) a[i], (V) a[++i]); } } return m; } /** * Returns a modifiable {@code Map} with the specified key and value. * * @param the type of keys in the Map * @param the type of values in the Map * @param k1 the key to be placed in the Map * @param v1 the value to be associated with the key in the Map * @return a Map containing the specified key and value */ public static Map asMap(final K k1, final V v1) { final Map map = newHashMap(1); map.put(k1, v1); return map; } /** * Returns a modifiable {@code Map} with the specified keys and values. * * @param the type of keys in the Map * @param the type of values in the Map * @param k1 the first key to be placed in the Map * @param v1 the value to be associated with the first key in the Map * @param k2 the second key to be placed in the Map * @param v2 the value to be associated with the second key in the Map * @return a Map containing the specified keys and values */ public static Map asMap(final K k1, final V v1, final K k2, final V v2) { final Map map = newHashMap(2); map.put(k1, v1); map.put(k2, v2); return map; } /** * Returns a modifiable {@code Map} with specified keys/values. * * @param the key type * @param the value type * @param k1 the first key to be placed in the Map * @param v1 the value to be associated with the first key in the Map * @param k2 the second key to be placed in the Map * @param v2 the value to be associated with the second key in the Map * @param k3 the third key to be placed in the Map * @param v3 the value to be associated with the third key in the Map * @return a Map containing the specified keys and values */ public static Map asMap(final K k1, final V v1, final K k2, final V v2, final K k3, final V v3) { final Map map = newHashMap(3); map.put(k1, v1); map.put(k2, v2); map.put(k3, v3); return map; } /** * Returns a modifiable {@code Map} with specified keys/values. * * @param the key type * @param the value type * @param k1 the first key to be placed in the Map * @param v1 the value to be associated with the first key in the Map * @param k2 the second key to be placed in the Map * @param v2 the value to be associated with the second key in the Map * @param k3 the third key to be placed in the Map * @param v3 the value to be associated with the third key in the Map * @param k4 the fourth key to be placed in the Map * @param v4 the value to be associated with the fourth key in the Map * @return a Map containing the specified keys and values */ public static Map asMap(final K k1, final V v1, final K k2, final V v2, final K k3, final V v3, final K k4, final V v4) { final Map map = newHashMap(4); map.put(k1, v1); map.put(k2, v2); map.put(k3, v3); map.put(k4, v4); return map; } /** * Returns a modifiable {@code Map} with specified keys/values. * * @param the key type * @param the value type * @param k1 the first key to be placed in the Map * @param v1 the value to be associated with the first key in the Map * @param k2 the second key to be placed in the Map * @param v2 the value to be associated with the second key in the Map * @param k3 the third key to be placed in the Map * @param v3 the value to be associated with the third key in the Map * @param k4 the fourth key to be placed in the Map * @param v4 the value to be associated with the fourth key in the Map * @param k5 the fifth key to be placed in the Map * @param v5 the value to be associated with the fifth key in the Map * @return a Map containing the specified keys and values */ public static Map asMap(final K k1, final V v1, final K k2, final V v2, final K k3, final V v3, final K k4, final V v4, final K k5, final V v5) { final Map map = newHashMap(5); map.put(k1, v1); map.put(k2, v2); map.put(k3, v3); map.put(k4, v4); map.put(k5, v5); return map; } /** * Returns a modifiable {@code Map} with specified keys/values. * * @param the key type * @param the value type * @param k1 the first key to be placed in the Map * @param v1 the value to be associated with the first key in the Map * @param k2 the second key to be placed in the Map * @param v2 the value to be associated with the second key in the Map * @param k3 the third key to be placed in the Map * @param v3 the value to be associated with the third key in the Map * @param k4 the fourth key to be placed in the Map * @param v4 the value to be associated with the fourth key in the Map * @param k5 the fifth key to be placed in the Map * @param v5 the value to be associated with the fifth key in the Map * @param k6 the sixth key to be placed in the Map * @param v6 the value to be associated with the sixth key in the Map * @return a Map containing the specified keys and values */ public static Map asMap(final K k1, final V v1, final K k2, final V v2, final K k3, final V v3, final K k4, final V v4, final K k5, final V v5, final K k6, final V v6) { final Map map = newHashMap(6); map.put(k1, v1); map.put(k2, v2); map.put(k3, v3); map.put(k4, v4); map.put(k5, v5); map.put(k6, v6); return map; } /** * Returns a modifiable {@code Map} with specified keys/values. * * @param the key type * @param the value type * @param k1 the first key to be placed in the Map * @param v1 the value to be associated with the first key in the Map * @param k2 the second key to be placed in the Map * @param v2 the value to be associated with the second key in the Map * @param k3 the third key to be placed in the Map * @param v3 the value to be associated with the third key in the Map * @param k4 the fourth key to be placed in the Map * @param v4 the value to be associated with the fourth key in the Map * @param k5 the fifth key to be placed in the Map * @param v5 the value to be associated with the fifth key in the Map * @param k6 the sixth key to be placed in the Map * @param v6 the value to be associated with the sixth key in the Map * @param k7 the seventh key to be placed in the Map * @param v7 the value to be associated with the seventh key in the Map * @return a Map containing the specified keys and values */ public static Map asMap(final K k1, final V v1, final K k2, final V v2, final K k3, final V v3, final K k4, final V v4, final K k5, final V v5, final K k6, final V v6, final K k7, final V v7) { final Map map = newHashMap(7); map.put(k1, v1); map.put(k2, v2); map.put(k3, v3); map.put(k4, v4); map.put(k5, v5); map.put(k6, v6); map.put(k7, v7); return map; } /** * Returns a modifiable {@code Map} with specified key/value pairs. * * @param the key type * @param the value type * @param a an array of key/value pairs * @return a Map containing the specified key/value pairs * @deprecated */ @Deprecated @NullSafe public static Map asMap(final Object... a) { if (isEmpty(a)) { return new HashMap<>(); } return newMap(newHashMap(a.length / 2), a); } /** * Returns a modifiable {@code LinkedHashMap} with specified key and value. * * @param the key type * @param the value type * @param k1 the first key to be placed in the Map * @param v1 the value to be associated with the first key in the Map * @return a Map containing the specified keys and values */ public static Map asLinkedHashMap(final K k1, final V v1) { final Map map = newLinkedHashMap(1); map.put(k1, v1); return map; } /** * Returns a modifiable {@code LinkedHashMap} with specified keys/values. * * @param the key type * @param the value type * @param k1 the first key to be placed in the Map * @param v1 the value to be associated with the first key in the Map * @param k2 the second key to be placed in the Map * @param v2 the value to be associated with the second key in the Map * @return a Map containing the specified keys and values */ public static Map asLinkedHashMap(final K k1, final V v1, final K k2, final V v2) { final Map map = newLinkedHashMap(2); map.put(k1, v1); map.put(k2, v2); return map; } /** * Returns a modifiable {@code LinkedHashMap} with specified keys/values. * * @param the key type * @param the value type * @param k1 the first key to be placed in the Map * @param v1 the value to be associated with the first key in the Map * @param k2 the second key to be placed in the Map * @param v2 the value to be associated with the second key in the Map * @param k3 the third key to be placed in the Map * @param v3 the value to be associated with the third key in the Map * @return a Map containing the specified keys and values */ public static Map asLinkedHashMap(final K k1, final V v1, final K k2, final V v2, final K k3, final V v3) { final Map map = newLinkedHashMap(3); map.put(k1, v1); map.put(k2, v2); map.put(k3, v3); return map; } /** * Returns a modifiable {@code LinkedHashMap} with specified keys/values. * * @param the key type * @param the value type * @param k1 the first key to be placed in the Map * @param v1 the value to be associated with the first key in the Map * @param k2 the second key to be placed in the Map * @param v2 the value to be associated with the second key in the Map * @param k3 the third key to be placed in the Map * @param v3 the value to be associated with the third key in the Map * @param k4 the fourth key to be placed in the Map * @param v4 the value to be associated with the fourth key in the Map * @return a Map containing the specified keys and values */ public static Map asLinkedHashMap(final K k1, final V v1, final K k2, final V v2, final K k3, final V v3, final K k4, final V v4) { final Map map = newLinkedHashMap(4); map.put(k1, v1); map.put(k2, v2); map.put(k3, v3); map.put(k4, v4); return map; } /** * Returns a modifiable {@code LinkedHashMap} with specified keys/values. * * @param the key type * @param the value type * @param k1 the first key to be placed in the Map * @param v1 the value to be associated with the first key in the Map * @param k2 the second key to be placed in the Map * @param v2 the value to be associated with the second key in the Map * @param k3 the third key to be placed in the Map * @param v3 the value to be associated with the third key in the Map * @param k4 the fourth key to be placed in the Map * @param v4 the value to be associated with the fourth key in the Map * @param k5 the fifth key to be placed in the Map * @param v5 the value to be associated with the fifth key in the Map * @return a Map containing the specified keys and values */ public static Map asLinkedHashMap(final K k1, final V v1, final K k2, final V v2, final K k3, final V v3, final K k4, final V v4, final K k5, final V v5) { final Map map = newLinkedHashMap(5); map.put(k1, v1); map.put(k2, v2); map.put(k3, v3); map.put(k4, v4); map.put(k5, v5); return map; } /** * Returns a modifiable {@code LinkedHashMap} with specified keys/values. * * @param the key type * @param the value type * @param k1 the first key to be placed in the Map * @param v1 the value to be associated with the first key in the Map * @param k2 the second key to be placed in the Map * @param v2 the value to be associated with the second key in the Map * @param k3 the third key to be placed in the Map * @param v3 the value to be associated with the third key in the Map * @param k4 the fourth key to be placed in the Map * @param v4 the value to be associated with the fourth key in the Map * @param k5 the fifth key to be placed in the Map * @param v5 the value to be associated with the fifth key in the Map * @param k6 the sixth key to be placed in the Map * @param v6 the value to be associated with the sixth key in the Map * @return a Map containing the specified keys and values */ public static Map asLinkedHashMap(final K k1, final V v1, final K k2, final V v2, final K k3, final V v3, final K k4, final V v4, final K k5, final V v5, final K k6, final V v6) { final Map map = newLinkedHashMap(6); map.put(k1, v1); map.put(k2, v2); map.put(k3, v3); map.put(k4, v4); map.put(k5, v5); map.put(k6, v6); return map; } /** * Returns a modifiable {@code LinkedHashMap} with specified keys/values. * * @param the key type * @param the value type * @param k1 the first key to be placed in the Map * @param v1 the value to be associated with the first key in the Map * @param k2 the second key to be placed in the Map * @param v2 the value to be associated with the second key in the Map * @param k3 the third key to be placed in the Map * @param v3 the value to be associated with the third key in the Map * @param k4 the fourth key to be placed in the Map * @param v4 the value to be associated with the fourth key in the Map * @param k5 the fifth key to be placed in the Map * @param v5 the value to be associated with the fifth key in the Map * @param k6 the sixth key to be placed in the Map * @param v6 the value to be associated with the sixth key in the Map * @param k7 the seventh key to be placed in the Map * @param v7 the value to be associated with the seventh key in the Map * @return a Map containing the specified keys and values */ public static Map asLinkedHashMap(final K k1, final V v1, final K k2, final V v2, final K k3, final V v3, final K k4, final V v4, final K k5, final V v5, final K k6, final V v6, final K k7, final V v7) { final Map map = newLinkedHashMap(7); map.put(k1, v1); map.put(k2, v2); map.put(k3, v3); map.put(k4, v4); map.put(k5, v5); map.put(k6, v6); map.put(k7, v7); return map; } /** * Returns a modifiable {@code LinkedHashMap} with specified key/value pairs. * * @param the key type * @param the value type * @param a an array of key/value pairs * @return a Map containing the specified key/value pairs * @deprecated */ @Deprecated @NullSafe public static Map asLinkedHashMap(final Object... a) { if (isEmpty(a)) { return newLinkedHashMap(); } return newMap(newLinkedHashMap(a.length / 2), a); } /** * Returns a modifiable {@code Map} with a specified key/value. * * @param propName the name of the property to be placed in the Map * @param propValue the value to be associated with the property name in the Map * @return a Map containing the specified property name and value */ @Beta public static Map asProps(final String propName, final Object propValue) { final Map props = newLinkedHashMap(1); props.put(propName, propValue); return props; } /** * Returns a modifiable {@code Map} with specified keys/values. * * @param propName1 the first property name to be placed in the Map * @param propValue1 the value to be associated with the first property name in the Map * @param propName2 the second property name to be placed in the Map * @param propValue2 the value to be associated with the second property name in the Map * @return a Map containing the specified property names and values */ public static Map asProps(final String propName1, final Object propValue1, final String propName2, final Object propValue2) { final Map props = newLinkedHashMap(2); props.put(propName1, propValue1); props.put(propName2, propValue2); return props; } /** * Returns a modifiable {@code Map} with specified keys/values. * * @param propName1 the first property name to be placed in the Map * @param propValue1 the value to be associated with the first property name in the Map * @param propName2 the second property name to be placed in the Map * @param propValue2 the value to be associated with the second property name in the Map * @param propName3 the third property name to be placed in the Map * @param propValue3 the value to be associated with the third property name in the Map * @return a Map containing the specified property names and values */ public static Map asProps(final String propName1, final Object propValue1, final String propName2, final Object propValue2, final String propName3, final Object propValue3) { final Map props = newLinkedHashMap(3); props.put(propName1, propValue1); props.put(propName2, propValue2); props.put(propName3, propValue3); return props; } /** * Returns a modifiable {@code Map} with specified keys/values. * * @param propName1 the first property name to be placed in the Map * @param propValue1 the value to be associated with the first property name in the Map * @param propName2 the second property name to be placed in the Map * @param propValue2 the value to be associated with the second property name in the Map * @param propName3 the third property name to be placed in the Map * @param propValue3 the value to be associated with the third property name in the Map * @param propName4 the fourth property name to be placed in the Map * @param propValue4 the value to be associated with the fourth property name in the Map * @return a Map containing the specified property names and values */ public static Map asProps(final String propName1, final Object propValue1, final String propName2, final Object propValue2, final String propName3, final Object propValue3, final String propName4, final Object propValue4) { final Map props = newLinkedHashMap(4); props.put(propName1, propValue1); props.put(propName2, propValue2); props.put(propName3, propValue3); props.put(propName4, propValue4); return props; } /** * Returns a modifiable {@code Map} with specified keys/values. * * @param propName1 the first property name to be placed in the Map * @param propValue1 the value to be associated with the first property name in the Map * @param propName2 the second property name to be placed in the Map * @param propValue2 the value to be associated with the second property name in the Map * @param propName3 the third property name to be placed in the Map * @param propValue3 the value to be associated with the third property name in the Map * @param propName4 the fourth property name to be placed in the Map * @param propValue4 the value to be associated with the fourth property name in the Map * @param propName5 the fifth property name to be placed in the Map * @param propValue5 the value to be associated with the fifth property name in the Map * @return a Map containing the specified property names and values */ public static Map asProps(final String propName1, final Object propValue1, final String propName2, final Object propValue2, final String propName3, final Object propValue3, final String propName4, final Object propValue4, final String propName5, final Object propValue5) { final Map props = newLinkedHashMap(5); props.put(propName1, propValue1); props.put(propName2, propValue2); props.put(propName3, propValue3); props.put(propName4, propValue4); props.put(propName5, propValue5); return props; } /** * Returns a modifiable {@code Map} with specified key/value pairs. * * @param a an array of key/value pairs * @return a Map containing the specified key/value pairs * @deprecated */ @Deprecated public static Map asProps(final Object... a) { if (isEmpty(a)) { return newLinkedHashMap(); } return newMap(newLinkedHashMap(a.length / 2), a); } /** * Returns a modifiable {@code List} with the specified element. * * @param the type of the element * @param e the element to be placed in the List * @return a List containing the specified element */ public static List asList(final T e) { final List list = new ArrayList<>(1); list.add(e); return list; } /** * Returns a modifiable {@code List} with specified elements. * * @param the type of elements in the list * @param e1 the first element to be placed in the List * @param e2 the second element to be placed in the List * @return a List containing the specified elements */ public static List asList(final T e1, final T e2) { final List list = new ArrayList<>(2); list.add(e1); list.add(e2); return list; } /** * Returns a modifiable {@code List} with specified elements. * * @param the type of elements in the list * @param e1 the first element to be placed in the List * @param e2 the second element to be placed in the List * @param e3 the third element to be placed in the List * @return a List containing the specified elements */ public static List asList(final T e1, final T e2, final T e3) { final List list = new ArrayList<>(3); list.add(e1); list.add(e2); list.add(e3); return list; } /** * Returns a modifiable {@code List} with specified elements. * * @param the type of elements in the list * @param e1 the first element to be placed in the List * @param e2 the second element to be placed in the List * @param e3 the third element to be placed in the List * @param e4 the fourth element to be placed in the List * @return a List containing the specified elements */ public static List asList(final T e1, final T e2, final T e3, final T e4) { final List list = new ArrayList<>(4); list.add(e1); list.add(e2); list.add(e3); list.add(e4); return list; } /** * Returns a modifiable {@code List} with specified elements. * * @param the type of elements in the list * @param e1 the first element to be placed in the List * @param e2 the second element to be placed in the List * @param e3 the third element to be placed in the List * @param e4 the fourth element to be placed in the List * @param e5 the fifth element to be placed in the List * @return a List containing the specified elements */ public static List asList(final T e1, final T e2, final T e3, final T e4, final T e5) { final List list = new ArrayList<>(5); list.add(e1); list.add(e2); list.add(e3); list.add(e4); list.add(e5); return list; } /** * Returns a modifiable {@code List} with specified elements. * * @param the type of elements in the list * @param e1 the first element to be placed in the List * @param e2 the second element to be placed in the List * @param e3 the third element to be placed in the List * @param e4 the fourth element to be placed in the List * @param e5 the fifth element to be placed in the List * @param e6 the sixth element to be placed in the List * @return a List containing the specified elements */ public static List asList(final T e1, final T e2, final T e3, final T e4, final T e5, final T e6) { final List list = new ArrayList<>(6); list.add(e1); list.add(e2); list.add(e3); list.add(e4); list.add(e5); list.add(e6); return list; } /** * Returns a modifiable {@code List} with specified elements. * * @param the type of elements in the list * @param e1 the first element to be placed in the List * @param e2 the second element to be placed in the List * @param e3 the third element to be placed in the List * @param e4 the fourth element to be placed in the List * @param e5 the fifth element to be placed in the List * @param e6 the sixth element to be placed in the List * @param e7 the seventh element to be placed in the List * @return a List containing the specified elements */ public static List asList(final T e1, final T e2, final T e3, final T e4, final T e5, final T e6, final T e7) { final List list = new ArrayList<>(7); list.add(e1); list.add(e2); list.add(e3); list.add(e4); list.add(e5); list.add(e6); list.add(e7); return list; } /** * Returns a modifiable {@code List} with specified elements. * * @param the type of elements in the list * @param e1 the first element to be placed in the List * @param e2 the second element to be placed in the List * @param e3 the third element to be placed in the List * @param e4 the fourth element to be placed in the List * @param e5 the fifth element to be placed in the List * @param e6 the sixth element to be placed in the List * @param e7 the seventh element to be placed in the List * @param e8 the eighth element to be placed in the List * @return a List containing the specified elements */ public static List asList(final T e1, final T e2, final T e3, final T e4, final T e5, final T e6, final T e7, final T e8) { final List list = new ArrayList<>(8); list.add(e1); list.add(e2); list.add(e3); list.add(e4); list.add(e5); list.add(e6); list.add(e7); list.add(e8); return list; } /** * Returns a modifiable {@code List} with specified elements. * * @param the type of elements in the list * @param e1 the first element to be placed in the List * @param e2 the second element to be placed in the List * @param e3 the third element to be placed in the List * @param e4 the fourth element to be placed in the List * @param e5 the fifth element to be placed in the List * @param e6 the sixth element to be placed in the List * @param e7 the seventh element to be placed in the List * @param e8 the eighth element to be placed in the List * @param e9 the ninth element to be placed in the List * @return a List containing the specified elements */ public static List asList(final T e1, final T e2, final T e3, final T e4, final T e5, final T e6, final T e7, final T e8, final T e9) { final List list = new ArrayList<>(9); list.add(e1); list.add(e2); list.add(e3); list.add(e4); list.add(e5); list.add(e6); list.add(e7); list.add(e8); list.add(e9); return list; } /** * Returns a modifiable {@code List} with specified elements. And it's not backed by the specified array. * If the specified array is {@code null} or empty, an empty {@code List} is returned. * * @param the type of elements in the list * @param a the array of elements to be placed in the List * @return a List containing the specified elements * @see Array#asList(Object...) * @see Arrays#asList(Object...) * @see List#of(Object...) */ @SafeVarargs @NullSafe public static List asList(@NullSafe final T... a) { if (isEmpty(a)) { return new ArrayList<>(); } final List list = new ArrayList<>(a.length); list.addAll(Array.asList(a)); return list; } /** * Returns a modifiable {@code LinkedList} with the specified element. * * @param the type of the element * @param e the element to be placed in the List * @return a List containing the specified element */ public static LinkedList asLinkedList(final T e) { //NOSONAR final LinkedList list = new LinkedList<>(); list.add(e); return list; } /** * Returns a modifiable {@code LinkedList} with specified elements. * * @param the type of elements in the list * @param e1 the first element to be placed in the List * @param e2 the second element to be placed in the List * @return a List containing the specified elements */ public static LinkedList asLinkedList(final T e1, final T e2) { //NOSONAR final LinkedList list = new LinkedList<>(); list.add(e1); list.add(e2); return list; } /** * Returns a modifiable {@code LinkedList} with specified elements. * * @param the type of elements in the list * @param e1 the first element to be placed in the List * @param e2 the second element to be placed in the List * @param e3 the third element to be placed in the List * @return a List containing the specified elements */ public static LinkedList asLinkedList(final T e1, final T e2, final T e3) { //NOSONAR final LinkedList list = new LinkedList<>(); list.add(e1); list.add(e2); list.add(e3); return list; } /** * Returns a modifiable {@code LinkedList} with specified elements. * * @param the type of elements in the list * @param e1 the first element to be placed in the List * @param e2 the second element to be placed in the List * @param e3 the third element to be placed in the List * @param e4 the fourth element to be placed in the List * @return a List containing the specified elements */ public static LinkedList asLinkedList(final T e1, final T e2, final T e3, final T e4) { //NOSONAR final LinkedList list = new LinkedList<>(); list.add(e1); list.add(e2); list.add(e3); list.add(e4); return list; } /** * Returns a modifiable {@code LinkedList} with specified elements. * * @param the type of elements in the list * @param e1 the first element to be placed in the List * @param e2 the second element to be placed in the List * @param e3 the third element to be placed in the List * @param e4 the fourth element to be placed in the List * @param e5 the fifth element to be placed in the List * @return a List containing the specified elements */ public static LinkedList asLinkedList(final T e1, final T e2, final T e3, final T e4, final T e5) { //NOSONAR final LinkedList list = new LinkedList<>(); list.add(e1); list.add(e2); list.add(e3); list.add(e4); list.add(e5); return list; } /** * Returns a modifiable {@code LinkedList} with specified elements. * * @param the type of elements in the list * @param e1 the first element to be placed in the List * @param e2 the second element to be placed in the List * @param e3 the third element to be placed in the List * @param e4 the fourth element to be placed in the List * @param e5 the fifth element to be placed in the List * @param e6 the sixth element to be placed in the List * @return a List containing the specified elements */ public static LinkedList asLinkedList(final T e1, final T e2, final T e3, final T e4, final T e5, final T e6) { //NOSONAR final LinkedList list = new LinkedList<>(); list.add(e1); list.add(e2); list.add(e3); list.add(e4); list.add(e5); list.add(e6); return list; } /** * Returns a modifiable {@code LinkedList} with specified elements. * * @param the type of elements in the list * @param e1 the first element to be placed in the List * @param e2 the second element to be placed in the List * @param e3 the third element to be placed in the List * @param e4 the fourth element to be placed in the List * @param e5 the fifth element to be placed in the List * @param e6 the sixth element to be placed in the List * @param e7 the seventh element to be placed in the List * @return a List containing the specified elements */ public static LinkedList asLinkedList(final T e1, final T e2, final T e3, final T e4, final T e5, final T e6, final T e7) { //NOSONAR final LinkedList list = new LinkedList<>(); list.add(e1); list.add(e2); list.add(e3); list.add(e4); list.add(e5); list.add(e6); list.add(e7); return list; } /** * Returns a modifiable {@code LinkedList} with specified elements. And it's not backed by the specified array. * If the specified array is {@code null} or empty, an empty {@code List} is returned. * * @param the type of elements in the list * @param a the array of elements to be placed in the List * @return a List containing the specified elements * @see Array#asList(Object...) * @see Arrays#asList(Object...) * @see List#of(Object...) */ @SafeVarargs @NullSafe public static LinkedList asLinkedList(final T... a) { //NOSONAR if (isEmpty(a)) { return new LinkedList<>(); } return new LinkedList<>(Array.asList(a)); } /** * Returns a modifiable {@code Set} with the specified element. * * @param the type of elements in the set * @param e the element to be placed in the Set * @return a Set containing the specified element */ public static Set asSet(final T e) { final Set set = newHashSet(1); set.add(e); return set; } /** * Returns a modifiable {@code Set} with the specified elements. * * @param the type of elements in the set * @param e1 the first element to be placed in the Set * @param e2 the second element to be placed in the Set * @return a Set containing the specified elements */ public static Set asSet(final T e1, final T e2) { final Set set = newHashSet(2); set.add(e1); set.add(e2); return set; } /** * Returns a modifiable {@code Set} with the specified elements. * * @param the type of elements in the set * @param e1 the first element to be placed in the Set * @param e2 the second element to be placed in the Set * @param e3 the third element to be placed in the Set * @return a Set containing the specified elements */ public static Set asSet(final T e1, final T e2, final T e3) { final Set set = newHashSet(3); set.add(e1); set.add(e2); set.add(e3); return set; } /** * Returns a modifiable {@code Set} with the specified elements. * * @param the type of elements in the set * @param e1 the first element to be placed in the Set * @param e2 the second element to be placed in the Set * @param e3 the third element to be placed in the Set * @param e4 the fourth element to be placed in the Set * @return a Set containing the specified elements */ public static Set asSet(final T e1, final T e2, final T e3, final T e4) { final Set set = newHashSet(4); set.add(e1); set.add(e2); set.add(e3); set.add(e4); return set; } /** * Returns a modifiable {@code Set} with the specified elements. * * @param the type of elements in the set * @param e1 the first element to be placed in the Set * @param e2 the second element to be placed in the Set * @param e3 the third element to be placed in the Set * @param e4 the fourth element to be placed in the Set * @param e5 the fifth element to be placed in the Set * @return a Set containing the specified elements */ public static Set asSet(final T e1, final T e2, final T e3, final T e4, final T e5) { final Set set = newHashSet(5); set.add(e1); set.add(e2); set.add(e3); set.add(e4); set.add(e5); return set; } /** * Returns a modifiable {@code Set} with the specified elements. * * @param the type of elements in the set * @param e1 the first element to be placed in the Set * @param e2 the second element to be placed in the Set * @param e3 the third element to be placed in the Set * @param e4 the fourth element to be placed in the Set * @param e5 the fifth element to be placed in the Set * @param e6 the sixth element to be placed in the Set * @return a Set containing the specified elements */ public static Set asSet(final T e1, final T e2, final T e3, final T e4, final T e5, final T e6) { final Set set = newHashSet(6); set.add(e1); set.add(e2); set.add(e3); set.add(e4); set.add(e5); set.add(e6); return set; } /** * Returns a modifiable {@code Set} with the specified elements. * * @param the type of elements in the set * @param e1 the first element to be placed in the Set * @param e2 the second element to be placed in the Set * @param e3 the third element to be placed in the Set * @param e4 the fourth element to be placed in the Set * @param e5 the fifth element to be placed in the Set * @param e6 the sixth element to be placed in the Set * @param e7 the seventh element to be placed in the Set * @return a Set containing the specified elements */ public static Set asSet(final T e1, final T e2, final T e3, final T e4, final T e5, final T e6, final T e7) { final Set set = newHashSet(7); set.add(e1); set.add(e2); set.add(e3); set.add(e4); set.add(e5); set.add(e6); set.add(e7); return set; } /** * Returns a modifiable {@code Set} with the specified elements. * * @param the type of elements in the set * @param e1 the first element to be placed in the Set * @param e2 the second element to be placed in the Set * @param e3 the third element to be placed in the Set * @param e4 the fourth element to be placed in the Set * @param e5 the fifth element to be placed in the Set * @param e6 the sixth element to be placed in the Set * @param e7 the seventh element to be placed in the Set * @param e8 the eighth element to be placed in the Set * @return a Set containing the specified elements */ public static Set asSet(final T e1, final T e2, final T e3, final T e4, final T e5, final T e6, final T e7, final T e8) { final Set set = newHashSet(8); set.add(e1); set.add(e2); set.add(e3); set.add(e4); set.add(e5); set.add(e6); set.add(e7); set.add(e8); return set; } /** * Returns a modifiable {@code Set} with the specified elements. * * @param the type of elements in the set * @param e1 the first element to be placed in the Set * @param e2 the second element to be placed in the Set * @param e3 the third element to be placed in the Set * @param e4 the fourth element to be placed in the Set * @param e5 the fifth element to be placed in the Set * @param e6 the sixth element to be placed in the Set * @param e7 the seventh element to be placed in the Set * @param e8 the eighth element to be placed in the Set * @param e9 the ninth element to be placed in the Set * @return a Set containing the specified elements */ public static Set asSet(final T e1, final T e2, final T e3, final T e4, final T e5, final T e6, final T e7, final T e8, final T e9) { final Set set = newHashSet(9); set.add(e1); set.add(e2); set.add(e3); set.add(e4); set.add(e5); set.add(e6); set.add(e7); set.add(e8); set.add(e9); return set; } /** * Returns a modifiable {@code Set} with specified elements. And it's not backed by the specified array. * If the specified array is {@code null} or empty, an empty {@code Set} is returned. * * @param the type of elements in the set * @param a the array of elements to be placed in the set * @return a Set containing the specified elements */ @SafeVarargs @NullSafe public static Set asSet(final T... a) { if (isEmpty(a)) { return newHashSet(); } final Set set = newHashSet(a.length); set.addAll(Array.asList(a)); return set; } /** * Returns a modifiable {@code LinkedHashSet} with specified element. * * @param the type of elements in the set * @param e the element to be placed in the Set * @return a Set containing the specified element */ public static Set asLinkedHashSet(final T e) { final Set set = newLinkedHashSet(1); set.add(e); return set; } /** * Returns a modifiable {@code LinkedHashSet} with the specified elements. * * @param the type of elements in the set * @param e1 the first element to be placed in the Set * @param e2 the second element to be placed in the Set * @return a Set containing the specified elements */ public static Set asLinkedHashSet(final T e1, final T e2) { final Set set = newLinkedHashSet(2); set.add(e1); set.add(e2); return set; } /** * Returns a modifiable {@code LinkedHashSet} with the specified elements. * * @param the type of elements in the set * @param e1 the first element to be placed in the Set * @param e2 the second element to be placed in the Set * @param e3 the third element to be placed in the Set * @return a Set containing the specified elements */ public static Set asLinkedHashSet(final T e1, final T e2, final T e3) { final Set set = newLinkedHashSet(3); set.add(e1); set.add(e2); set.add(e3); return set; } /** * Returns a modifiable {@code LinkedHashSet} with the specified elements. * * @param the type of elements in the set * @param e1 the first element to be placed in the Set * @param e2 the second element to be placed in the Set * @param e3 the third element to be placed in the Set * @param e4 the fourth element to be placed in the Set * @return a Set containing the specified elements */ public static Set asLinkedHashSet(final T e1, final T e2, final T e3, final T e4) { final Set set = newLinkedHashSet(4); set.add(e1); set.add(e2); set.add(e3); set.add(e4); return set; } /** * Returns a modifiable {@code LinkedHashSet} with the specified elements. * * @param the type of elements in the set * @param e1 the first element to be placed in the Set * @param e2 the second element to be placed in the Set * @param e3 the third element to be placed in the Set * @param e4 the fourth element to be placed in the Set * @param e5 the fifth element to be placed in the Set * @return a Set containing the specified elements */ public static Set asLinkedHashSet(final T e1, final T e2, final T e3, final T e4, final T e5) { final Set set = newLinkedHashSet(5); set.add(e1); set.add(e2); set.add(e3); set.add(e4); set.add(e5); return set; } /** * Returns a modifiable {@code LinkedHashSet} with the specified elements. * * @param the type of elements in the set * @param e1 the first element to be placed in the Set * @param e2 the second element to be placed in the Set * @param e3 the third element to be placed in the Set * @param e4 the fourth element to be placed in the Set * @param e5 the fifth element to be placed in the Set * @param e6 the sixth element to be placed in the Set * @return a Set containing the specified elements */ public static Set asLinkedHashSet(final T e1, final T e2, final T e3, final T e4, final T e5, final T e6) { final Set set = newLinkedHashSet(6); set.add(e1); set.add(e2); set.add(e3); set.add(e4); set.add(e5); set.add(e6); return set; } /** * Returns a modifiable {@code LinkedHashSet} with the specified elements. * * @param the type of elements in the set * @param e1 the first element to be placed in the Set * @param e2 the second element to be placed in the Set * @param e3 the third element to be placed in the Set * @param e4 the fourth element to be placed in the Set * @param e5 the fifth element to be placed in the Set * @param e6 the sixth element to be placed in the Set * @param e7 the seventh element to be placed in the Set * @return a Set containing the specified elements */ public static Set asLinkedHashSet(final T e1, final T e2, final T e3, final T e4, final T e5, final T e6, final T e7) { final Set set = newLinkedHashSet(7); set.add(e1); set.add(e2); set.add(e3); set.add(e4); set.add(e5); set.add(e6); set.add(e7); return set; } /** * Returns a modifiable {@code LinkedHashSet} with specified elements. And it's not backed by the specified array. * If the specified array is {@code null} or empty, an empty {@code LinkedHashSet} is returned. * * @param the type of elements in the set * @param a the array of elements to be placed in the set * @return a Set containing the specified elements */ @SafeVarargs @NullSafe public static Set asLinkedHashSet(final T... a) { if (isEmpty(a)) { return newLinkedHashSet(); } final Set set = newLinkedHashSet(a.length); set.addAll(Array.asList(a)); return set; } /** * Returns a modifiable {@code SortedSet} with specified elements. And it's not backed by the specified array. * If the specified array is {@code null} or empty, an empty {@code SortedSet} is returned. * * @param the type of elements in the set * @param a the array of elements to be placed in the set * @return a Set containing the specified elements */ @SafeVarargs @NullSafe public static > SortedSet asSortedSet(final T... a) { if (isEmpty(a)) { return new TreeSet<>(); } return new TreeSet<>(Array.asList(a)); } /** * Returns a modifiable {@code NavigableSet} with specified elements. And it's not backed by the specified array. * If the specified array is {@code null} or empty, an empty {@code NavigableSet} is returned. * * @param the type of elements in the set * @param a the array of elements to be placed in the set * @return a Set containing the specified elements */ @SafeVarargs public static > NavigableSet asNavigableSet(final T... a) { if (isEmpty(a)) { return new TreeSet<>(); } return new TreeSet<>(Array.asList(a)); } /** * Returns a modifiable {@code Queue} with specified elements. And it's not backed by the specified array. * If the specified array is {@code null} or empty, an empty {@code Queue} is returned. * * @param the type of elements in the queue * @param a the array of elements to be placed in the queue * @return a queue containing the specified elements */ @SafeVarargs public static Queue asQueue(final T... a) { return asArrayDeque(a); } /** * Returns a modifiable {@code ArrayBlockingQueue} with specified elements. And it's not backed by the specified array. * If the specified array is {@code null} or empty, an empty {@code ArrayBlockingQueue} is returned. * * @param the type of elements in the queue * @param a the array of elements to be placed in the queue * @return a queue containing the specified elements */ @SafeVarargs public static ArrayBlockingQueue asArrayBlockingQueue(final T... a) { if (isEmpty(a)) { return new ArrayBlockingQueue<>(1); } final ArrayBlockingQueue queue = new ArrayBlockingQueue<>(a.length); queue.addAll(Array.asList(a)); return queue; } /** * Returns a modifiable {@code LinkedBlockingQueue} with specified elements. And it's not backed by the specified array. * If the specified array is {@code null} or empty, an empty {@code LinkedBlockingQueue} is returned. * * @param the type of elements in the queue * @param a the array of elements to be placed in the queue * @return a queue containing the specified elements */ @SafeVarargs public static LinkedBlockingQueue asLinkedBlockingQueue(final T... a) { if (isEmpty(a)) { return new LinkedBlockingQueue<>(); } final LinkedBlockingQueue queue = new LinkedBlockingQueue<>(a.length); queue.addAll(Array.asList(a)); return queue; } /** * Returns a modifiable {@code ConcurrentLinkedQueue} with specified elements. And it's not backed by the specified array. * If the specified array is {@code null} or empty, an empty {@code ConcurrentLinkedQueue} is returned. * * @param the type of elements in the queue * @param a the array of elements to be placed in the queue * @return a queue containing the specified elements */ @SafeVarargs public static ConcurrentLinkedQueue asConcurrentLinkedQueue(final T... a) { //NOSONAR if (isEmpty(a)) { return new ConcurrentLinkedQueue<>(); } return new ConcurrentLinkedQueue<>(Array.asList(a)); } /** * Returns a modifiable {@code DelayQueue} with specified elements. And it's not backed by the specified array. * If the specified array is {@code null} or empty, an empty {@code DelayQueue} is returned. * * @param the type of elements in the queue * @param a the array of elements to be placed in the queue * @return a queue containing the specified elements */ @SafeVarargs public static DelayQueue asDelayQueue(final T... a) { if (isEmpty(a)) { return new DelayQueue<>(); } return new DelayQueue<>(Array.asList(a)); } /** * Returns a modifiable {@code PriorityQueue} with specified elements. And it's not backed by the specified array. * If the specified array is {@code null} or empty, an empty {@code PriorityQueue} is returned. * * @param the type of elements in the queue * @param a the array of elements to be placed in the queue * @return a queue containing the specified elements */ @SafeVarargs public static PriorityQueue asPriorityQueue(final T... a) { if (isEmpty(a)) { return new PriorityQueue<>(); } final PriorityQueue queue = new PriorityQueue<>(a.length); queue.addAll(Array.asList(a)); return queue; } /** * Returns a modifiable {@code Deque} with specified elements. And it's not backed by the specified array. * If the specified array is {@code null} or empty, an empty {@code Deque} is returned. * * @param the type of elements in the deque * @param a the array of elements to be placed in the deque * @return a deque containing the specified elements */ @SafeVarargs public static Deque asDeque(final T... a) { return asArrayDeque(a); } /** * Returns a modifiable {@code ArrayDeque} with specified elements. And it's not backed by the specified array. * If the specified array is {@code null} or empty, an empty {@code ArrayDeque} is returned. * * @param the type of elements in the deque * @param a the array of elements to be placed in the deque * @return a deque containing the specified elements */ @SafeVarargs public static ArrayDeque asArrayDeque(final T... a) { //NOSONAR if (isEmpty(a)) { return new ArrayDeque<>(); } final ArrayDeque arrayDeque = new ArrayDeque<>(a.length); arrayDeque.addAll(Array.asList(a)); return arrayDeque; } /** * Returns a modifiable {@code asLinkedBlockingDeque} with specified elements. And it's not backed by the specified array. * If the specified array is {@code null} or empty, an empty {@code asLinkedBlockingDeque} is returned. * * @param the type of elements in the deque * @param a the array of elements to be placed in the deque * @return a deque containing the specified elements */ @SafeVarargs public static LinkedBlockingDeque asLinkedBlockingDeque(final T... a) { if (isEmpty(a)) { return new LinkedBlockingDeque<>(); } final LinkedBlockingDeque deque = new LinkedBlockingDeque<>(a.length); deque.addAll(Array.asList(a)); return deque; } /** * Returns a modifiable {@code ConcurrentLinkedDeque} with specified elements. And it's not backed by the specified array. * If the specified array is {@code null} or empty, an empty {@code ConcurrentLinkedDeque} is returned. * * @param the type of elements in the deque * @param a the array of elements to be placed in the deque * @return a deque containing the specified elements */ @SafeVarargs public static ConcurrentLinkedDeque asConcurrentLinkedDeque(final T... a) { //NOSONAR if (isEmpty(a)) { return new ConcurrentLinkedDeque<>(); } return new ConcurrentLinkedDeque<>(Array.asList(a)); } /** * Returns a modifiable {@code Multiset} with the specified elements. * If the specified array is {@code null} or empty, an empty modifiable {@code Multiset} is returned. * * @param the type of elements in the multiset * @param a the array of elements to be placed in the multiset * @return a Multiset containing the specified elements */ @SafeVarargs public static Multiset asMultiset(final T... a) { return Multiset.of(a); } /** * Returns an immutable list containing only the specified element. * * @param the type of the element * @param e the element to be wrapped in a singleton list * @return an immutable/unmodifiable list containing the specified element * @see java.util.Collections#singletonList(Object) */ @Immutable public static List asSingletonList(final T e) { return Collections.singletonList(e); } /** * Returns an immutable set containing only the specified element. * * @param the type of the element * @param e the element to be wrapped in a singleton set * @return an immutable/unmodifiable list containing the specified element * @see java.util.Collections#singleton(Object) */ @Immutable public static Set asSingletonSet(final T e) { return Collections.singleton(e); } /** * Returns an immutable map containing only the specified key-value pair. * * @param the type of keys maintained by the map * @param the type of mapped values * @param key the key to be placed in the map * @param value the value to be associated with the key * @return an immutable/unmodifiable map containing the specified key-value pair * @see java.util.Collections#singletonMap(Object, Object) */ @Immutable public static Map asSingletonMap(final K key, final V value) { return Collections.singletonMap(key, value); } /** * Returns an immutable/unmodifiable empty {@code List}. * * @param the type of elements in the list * @return an immutable/unmodifiable empty list * @see Collections#emptyList() */ @Immutable public static List emptyList() { return EMPTY_LIST; } /** * Returns an immutable/unmodifiable empty {@code Set}. * * @param the type of elements in the set * @return an immutable/unmodifiable empty set * @see Collections#emptySet() */ @Immutable public static Set emptySet() { return EMPTY_SET; } /** * Returns an immutable/unmodifiable empty {@code SortedSet}. * * @param the type of elements in the set * @return an immutable/unmodifiable empty set * @see Collections#emptySortedSet() */ @Immutable public static SortedSet emptySortedSet() { return EMPTY_SORTED_SET; } /** * Returns an immutable/unmodifiable empty {@code NavigableSet}. * * @param the type of elements in the set * @return an immutable/unmodifiable empty set * @see Collections#emptyNavigableSet() */ @Immutable public static NavigableSet emptyNavigableSet() { return EMPTY_NAVIGABLE_SET; } /** * Returns an immutable/unmodifiable empty {@code Map}. * * @param the key type * @param the value type * @return an immutable/unmodifiable empty map * @see Collections#emptyMap() */ @Immutable public static Map emptyMap() { return EMPTY_MAP; } /** * Returns an immutable/unmodifiable empty {@code SortedMap}. * * @param the key type * @param the value type * @return an immutable/unmodifiable empty sorted map * @see Collections#emptySortedMap() */ @Immutable public static SortedMap emptySortedMap() { return EMPTY_SORTED_MAP; } /** * Returns an immutable/unmodifiable empty {@code NavigableMap}. * * @param the key type * @param the value type * @return an immutable/unmodifiable empty navigable map * @see Collections#emptyNavigableMap() */ @Immutable public static NavigableMap emptyNavigableMap() { return EMPTY_NAVIGABLE_MAP; } /** * Returns an immutable/unmodifiable empty iterator. * * @param the type of elements returned by this iterator * @return an immutable/unmodifiable empty iterator * @see Collections#emptyIterator() */ public static Iterator emptyIterator() { return EMPTY_ITERATOR; } /** * Returns an immutable/unmodifiable empty {@code ListIterator}. * * @param the type of elements returned by this list iterator * @return an immutable/unmodifiable empty list iterator * @see Collections#emptyListIterator() */ @Immutable public static ListIterator emptyListIterator() { return EMPTY_LIST_ITERATOR; } private static final ByteArrayInputStream EMPTY_INPUT_STREAM = new ByteArrayInputStream(EMPTY_BYTE_ARRAY); /** * Returns an immutable/unmodifiable empty {@code InputStream}. * * @return an immutable/unmodifiable empty input stream * @see ByteArrayInputStream */ @Immutable public static InputStream emptyInputStream() { return EMPTY_INPUT_STREAM; } /** * Returns an immutable/unmodifiable empty {@code DataSet}. * * @return an immutable/unmodifiable empty DataSet * @see DataSet#empty() */ @Immutable public static DataSet emptyDataSet() { return DataSet.empty(); } /** * Retrieves the element at the specified position in the given Iterable. * * @param the type of elements in the iterable * @param c the iterable from which to retrieve the element * @param index the position of the element to retrieve * @return the element at the specified position in the iterable * @throws IllegalArgumentException if the iterable is null * @throws IndexOutOfBoundsException if the index is out of range */ public static T getElement(@NotNull final Iterable c, final int index) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNull(c, cs.c); if (c instanceof Collection) { checkElementIndex(index, ((Collection) c).size()); } if (c instanceof List) { return ((List) c).get(index); } return getElement(c.iterator(), index); } /** * Retrieves the element at the specified position in the given Iterator. * * @param the type of elements in the Iterator * @param iter the Iterator to retrieve the element from. Must not be {@code null}. * @param index the index of the element to retrieve. Must be a non-negative integer. * @return the element at the specified index in the Iterator * @throws IllegalArgumentException if the Iterator is null * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index >= size of Iterator) */ public static T getElement(@NotNull final Iterator iter, long index) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNull(iter, cs.iter); while (index-- > 0 && iter.hasNext()) { iter.next(); } if (iter.hasNext()) { return iter.next(); } else { throw new IndexOutOfBoundsException("Index: " + index + " is bigger than the maximum index of the specified Iterable or Iterator"); } } /** * Returns the only element in the given Iterable. * * @param the type of elements in the Iterable * @param c the Iterable to get the element from * @return a {@code Nullable} containing the only element in the Iterable if it exists, otherwise an empty Nullable * @throws TooManyElementsException if the Iterable contains more than one element */ public static Nullable getOnlyElement(final Iterable c) throws TooManyElementsException { if (isEmptyCollection(c)) { return Nullable.empty(); } if (c instanceof Collection && ((Collection) c).size() > 1) { final Iterator iter = c.iterator(); throw new TooManyElementsException("Expected at most one element but was: [" + Strings.concat(iter.next(), ", ", iter.next(), "...]")); } return getOnlyElement(c.iterator()); } /** * Returns the only element in the given Iterator. * * @param the type of elements in the Iterator * @param iter the Iterator to get the element from * @return a {@code Nullable} containing the only element in the Iterator if it exists, otherwise an empty Nullable * @throws TooManyElementsException if the Iterator contains more than one element */ public static Nullable getOnlyElement(final Iterator iter) throws TooManyElementsException { if (iter == null) { return Nullable.empty(); } final T first = iter.next(); if (iter.hasNext()) { throw new TooManyElementsException("Expected at most one element but was: [" + Strings.concat(first, ", ", iter.next(), "...]")); } return Nullable.of(first); } /** * Returns the first element in the given Iterable wrapped in a {@code Nullable}. * If the Iterable is empty, an empty {@code Nullable} is returned. * * @param the type of elements in the Iterable * @param c the Iterable to get the first element from * @return a {@code Nullable} containing the first element in the Iterable if it exists, otherwise an empty Nullable */ public static Nullable firstElement(final Iterable c) { if (isEmpty(c)) { return Nullable.empty(); } if (c instanceof List && c instanceof RandomAccess) { return Nullable.of(((List) c).get(0)); } else { return Nullable.of(c.iterator().next()); } } /** * Returns the first element in the given Iterator wrapped in a {@code Nullable}. * If the Iterator is empty, an empty {@code Nullable} is returned. * * @param the type of elements in the Iterator * @param iter the Iterator to get the first element from * @return a {@code Nullable} containing the first element in the Iterator if it exists, otherwise an empty Nullable */ public static Nullable firstElement(final Iterator iter) { return iter != null && iter.hasNext() ? Nullable.of(iter.next()) : Nullable.empty(); } /** * Returns the last element in the given Iterable wrapped in a {@code Nullable}. * If the Iterable is empty, an empty {@code Nullable} is returned. * * @param the type of elements in the Iterable * @param c the Iterable to get the last element from * @return a {@code Nullable} containing the last element in the Iterable if it exists, otherwise an empty Nullable */ public static Nullable lastElement(final Iterable c) { if (isEmpty(c)) { return Nullable.empty(); } if (c instanceof List && c instanceof RandomAccess) { final List list = (List) c; return Nullable.of(list.get(list.size() - 1)); } final Iterator descendingIterator = getDescendingIteratorIfPossible(c); if (descendingIterator != null) { return Nullable.of(descendingIterator.next()); } return lastElement(c.iterator()); } /** * Returns the last element in the given Iterator wrapped in a {@code Nullable}. * If the Iterator is empty, an empty {@code Nullable} is returned. * * @param the type of elements in the Iterator * @param iter the Iterator to get the last element from * @return a {@code Nullable} containing the last element in the Iterator if it exists, otherwise an empty Nullable */ public static Nullable lastElement(final Iterator iter) { if (iter == null || !iter.hasNext()) { return Nullable.empty(); } T e = null; while (iter.hasNext()) { e = iter.next(); } return Nullable.of(e); } /** * Returns a list containing the first n elements from the given Iterable. * If the Iterable has less than n elements, it returns a list with all the elements in the Iterable. * * @param the type of elements in the Iterable * @param c the Iterable to get the elements from * @param n the number of elements to retrieve from the Iterable * @return a list containing the first n elements from the Iterable * @throws IllegalArgumentException if n is negative */ @Beta public static List firstElements(final Iterable c, final int n) throws IllegalArgumentException { checkArgument(n >= 0, "'n' can't be negative: " + n); if (isEmpty(c) || n == 0) { return new ArrayList<>(); } if (c instanceof final Collection coll) { // NOSONAR if (coll.size() <= n) { return new ArrayList<>(coll); } else if (coll instanceof final List list) { // NOSONAR return new ArrayList<>((list).subList(0, n)); } } final List result = new ArrayList<>(Math.min(1024, n)); int cnt = 0; for (final T e : c) { result.add(e); if (++cnt == n) { break; } } return result; } /** * Returns a list containing the first n elements from the given Iterator. * If the Iterator has less than n elements, it returns a list with all the elements in the Iterator. * * @param the type of elements in the Iterator * @param iter the Iterator to get the elements from * @param n the number of elements to retrieve from the Iterator * @return a list containing the first n elements from the Iterator * @throws IllegalArgumentException if n is negative */ @Beta public static List firstElements(final Iterator iter, final int n) throws IllegalArgumentException { checkArgument(n >= 0, "'n' can't be negative: " + n); if (isEmpty(iter) || n == 0) { return new ArrayList<>(); } final List result = new ArrayList<>(Math.min(1024, n)); int cnt = 0; while (iter.hasNext()) { result.add(iter.next()); if (++cnt == n) { break; } } return result; } /** * Returns a list containing the last n elements from the given Iterable. * If the Iterable has less than n elements, it returns a list with all the elements in the Iterable. * * @param the type of elements in the Iterable * @param c the Iterable to get the elements from * @param n the number of elements to retrieve from the end of the Iterable * @return a list containing the last n elements from the Iterable * @throws IllegalArgumentException if n is negative */ @Beta public static List lastElements(final Iterable c, final int n) throws IllegalArgumentException { checkArgument(n >= 0, "'n' can't be negative: " + n); if (isEmpty(c) || n == 0) { return new ArrayList<>(); } if (c instanceof final Collection coll) { // NOSONAR if (coll.size() <= n) { return new ArrayList<>(coll); } else if (coll instanceof final List list) { // NOSONAR return new ArrayList<>(list.subList(list.size() - n, list.size())); } } final Deque deque = new ArrayDeque<>(Math.min(1024, n)); for (final T e : c) { if (deque.size() >= n) { deque.pollFirst(); } deque.offerLast(e); } return new ArrayList<>(deque); } /** * Returns a list containing the last n elements from the given Iterator. * If the Iterator has less than n elements, it returns a list with all the elements in the Iterator. * * @param the type of elements in the Iterator * @param iter the Iterator to get the elements from * @param n the number of elements to retrieve from the Iterator * @return a list containing the last n elements from the Iterator * @throws IllegalArgumentException if n is negative */ @Beta public static List lastElements(final Iterator iter, final int n) throws IllegalArgumentException { checkArgument(n >= 0, "'n' can't be negative: " + n); if (isEmpty(iter) || n == 0) { return new ArrayList<>(); } final Deque deque = new ArrayDeque<>(Math.min(1024, n)); while (iter.hasNext()) { if (deque.size() >= n) { deque.pollFirst(); } deque.offerLast(iter.next()); } return new ArrayList<>(deque); } /** * Returns the first {@code non-null} value among the two provided values. * If both values are {@code null}, it returns an empty Optional. * * @param the type of the values * @param a the first value to check * @param b the second value to check * @return an Optional containing the first {@code non-null} value if it exists, otherwise an empty Optional */ public static Optional firstNonNull(final T a, final T b) { return a != null ? Optional.of(a) : (b != null ? Optional.of(b) : Optional.empty()); } /** * Returns the first {@code non-null} value among the three provided values. * If all values are {@code null}, it returns an empty Optional. * * @param the type of the values * @param a the first value to check * @param b the second value to check * @param c the third value to check * @return an Optional containing the first {@code non-null} value if it exists, otherwise an empty Optional */ public static Optional firstNonNull(final T a, final T b, final T c) { return a != null ? Optional.of(a) : (b != null ? Optional.of(b) : (c != null ? Optional.of(c) : Optional.empty())); } /** * Returns the first {@code non-null} value among the provided values. * If all values are {@code null}, it returns an empty Optional. * * @param the type of the values * @param a the array of values to check * @return an Optional containing the first {@code non-null} value if it exists, otherwise an empty Optional */ @SafeVarargs public static Optional firstNonNull(final T... a) { if (isEmpty(a)) { return Optional.empty(); } for (final T e : a) { if (e != null) { return Optional.of(e); } } return Optional.empty(); } /** * Returns the first {@code non-null} value from the provided iterable. * If all values are {@code null}, it returns an empty Optional. * * @param the type of the values * @param c the iterable of values to check * @return an Optional containing the first {@code non-null} value if it exists, otherwise an empty Optional */ public static Optional firstNonNull(final Iterable c) { if (isEmpty(c)) { return Optional.empty(); } for (final T e : c) { if (e != null) { return Optional.of(e); } } return Optional.empty(); } /** * Returns the first {@code non-null} value from the provided iterator. * If all values are {@code null}, it returns an empty Optional. * * @param the type of the values * @param iter the iterator of values to check * @return an Optional containing the first {@code non-null} value if it exists, otherwise an empty Optional */ public static Optional firstNonNull(final Iterator iter) { if (iter == null) { return Optional.empty(); } T e = null; while (iter.hasNext()) { if ((e = iter.next()) != null) { return Optional.of(e); } } return Optional.empty(); } /** * Returns the last {@code non-null} value from the provided values. * If both values are {@code null}, it returns an empty Optional. * * @param the type of the values * @param a the first value to check * @param b the second value to check * @return an Optional containing the last {@code non-null} value if it exists, otherwise an empty Optional */ public static Optional lastNonNull(final T a, final T b) { return b != null ? Optional.of(b) : (a != null ? Optional.of(a) : Optional.empty()); } /** * Returns the last {@code non-null} value from the provided values. * If all values are {@code null}, it returns an empty Optional. * * @param the type of the values * @param a the first value to check * @param b the second value to check * @param c the third value to check * @return an Optional containing the last {@code non-null} value if it exists, otherwise an empty Optional */ public static Optional lastNonNull(final T a, final T b, final T c) { return c != null ? Optional.of(c) : (b != null ? Optional.of(b) : (a != null ? Optional.of(a) : Optional.empty())); } /** * Returns the last {@code non-null} value from the provided array of values. * If all values are {@code null}, it returns an empty Optional. * * @param the type of the values * @param a the array of values to check * @return an Optional containing the last {@code non-null} value if it exists, otherwise an empty Optional */ @SafeVarargs public static Optional lastNonNull(final T... a) { if (isEmpty(a)) { return Optional.empty(); } for (int i = a.length - 1; i >= 0; i--) { if (a[i] != null) { return Optional.of(a[i]); } } return Optional.empty(); } /** * Returns the last {@code non-null} value from the provided iterable. * If all values are {@code null}, it returns an empty Optional. * * @param the type of the values * @param c the iterable to check * @return an Optional containing the last {@code non-null} value if it exists, otherwise an empty Optional */ public static Optional lastNonNull(final Iterable c) { if (isEmpty(c)) { return Optional.empty(); } if (c instanceof List && c instanceof RandomAccess) { final List list = (List) c; for (int i = list.size() - 1; i >= 0; i--) { if (list.get(i) != null) { return Optional.of(list.get(i)); } } return Optional.empty(); } final Iterator descendingIterator = getDescendingIteratorIfPossible(c); if (descendingIterator != null) { T next = null; while (descendingIterator.hasNext()) { if ((next = descendingIterator.next()) != null) { return Optional.of(next); } } return Optional.empty(); } return lastNonNull(c.iterator()); } /** * Returns the last {@code non-null} value from the provided iterator. * If all values are {@code null}, it returns an empty Optional. * * @param the type of the values * @param iter the iterator to check * @return an Optional containing the last {@code non-null} value if it exists, otherwise an empty Optional */ public static Optional lastNonNull(final Iterator iter) { if (iter == null) { return Optional.empty(); } T e = null; T lastNonNull = null; while (iter.hasNext()) { if ((e = iter.next()) != null) { lastNonNull = e; } } return Optional.ofNullable(lastNonNull); } /** * Returns the first non-empty array from the given arrays. * If both arrays are empty or {@code null}, it returns an empty Optional. * * @param the type of elements in the arrays * @param a the first array to check * @param b the second array to check * @return an Optional containing the first non-empty array, or an empty Optional if both arrays are empty or null */ public static Optional firstNonEmpty(final T[] a, final T[] b) { return a != null && a.length > 0 ? Optional.of(a) : (b != null && b.length > 0 ? Optional.of(b) : Optional.empty()); } /** * Returns the first non-empty array from the given arrays. * If all arrays are empty or {@code null}, it returns an empty Optional. * * @param the type of elements in the arrays * @param a the first array to check * @param b the second array to check * @param c the third array to check * @return an Optional containing the first non-empty array, or an empty Optional if all arrays are empty or null */ public static Optional firstNonEmpty(final T[] a, final T[] b, final T[] c) { return a != null && a.length > 0 ? Optional.of(a) : (b != null && b.length > 0 ? Optional.of(b) : (c != null && c.length > 0 ? Optional.of(c) : Optional.empty())); } /** * Returns the first non-empty collection from the given collections. * If both collections are empty or {@code null}, it returns an empty Optional. * * @param the type of the collections * @param a the first collection to check * @param b the second collection to check * @return an Optional containing the first non-empty collection, or an empty Optional if both collections are empty or null */ public static > Optional firstNonEmpty(final T a, final T b) { return a != null && a.size() > 0 ? Optional.of(a) : (b != null && b.size() > 0 ? Optional.of(b) : Optional.empty()); } /** * Returns the first non-empty collection from the given collections. * If all collections are empty or {@code null}, it returns an empty Optional. * * @param the type of the collections * @param a the first collection to check * @param b the second collection to check * @param c the third collection to check * @return an Optional containing the first non-empty collection, or an empty Optional if all collections are empty or null */ public static > Optional firstNonEmpty(final T a, final T b, final T c) { return a != null && a.size() > 0 ? Optional.of(a) : (b != null && b.size() > 0 ? Optional.of(b) : (c != null && c.size() > 0 ? Optional.of(c) : Optional.empty())); } /** * Returns the first non-empty map from the given maps. * If both maps are empty or {@code null}, it returns an empty Optional. * * @param the type of the maps * @param a the first map to check * @param b the second map to check * @return an Optional containing the first non-empty map, or an empty Optional if both maps are empty or null */ public static > Optional firstNonEmpty(final T a, final T b) { return a != null && !a.isEmpty() ? Optional.of(a) : (b != null && !b.isEmpty() ? Optional.of(b) : Optional.empty()); } /** * Returns the first non-empty map from the given maps. * If all maps are empty or {@code null}, it returns an empty Optional. * * @param the type of the maps * @param a the first map to check * @param b the second map to check * @param c the third map to check * @return an Optional containing the first non-empty map, or an empty Optional if all maps are empty or null */ public static > Optional firstNonEmpty(final T a, final T b, final T c) { return a != null && !a.isEmpty() ? Optional.of(a) : (b != null && !b.isEmpty() ? Optional.of(b) : (c != null && !c.isEmpty() ? Optional.of(c) : Optional.empty())); } /** * Returns the first non-empty CharSequence from the given CharSequences. * If both CharSequences are empty or {@code null}, it returns an empty Optional. * * @param the type of the CharSequences * @param a the first CharSequence to check * @param b the second CharSequence to check * @return an Optional containing the first non-empty CharSequence, or an empty Optional if both CharSequences are empty or null * @see Strings#firstNonEmpty(CharSequence, CharSequence) */ public static Optional firstNonEmpty(final T a, final T b) { return Strings.isNotEmpty(a) ? Optional.of(a) : (Strings.isNotEmpty(b) ? Optional.of(b) : Optional.empty()); } /** * Returns the first non-empty CharSequence from the given CharSequences. * If all CharSequences are empty or {@code null}, it returns an empty Optional. * * @param the type of the CharSequences * @param a the first CharSequence to check * @param b the second CharSequence to check * @param c the third CharSequence to check * @return an Optional containing the first non-empty CharSequence, or an empty Optional if all CharSequences are empty or null * @see Strings#firstNonEmpty(CharSequence, CharSequence, CharSequence) */ public static Optional firstNonEmpty(final T a, final T b, final T c) { return Strings.isNotEmpty(a) ? Optional.of(a) : (Strings.isNotEmpty(b) ? Optional.of(b) : (Strings.isNotEmpty(c) ? Optional.of(c) : Optional.empty())); } /** * Returns the first non-empty CharSequence from the given CharSequences. * If all CharSequences are empty or {@code null}, it returns an empty Optional. * * @param the type of the CharSequences * @param a the array of CharSequences to check * @return an Optional containing the first non-empty CharSequence, or an empty Optional if all CharSequences are empty or null * @see Strings#firstNonEmpty(CharSequence...) */ @SafeVarargs public static Optional firstNonEmpty(final T... a) { if (isEmpty(a)) { return Optional.empty(); } for (final T e : a) { if (Strings.isNotEmpty(e)) { return Optional.of(e); } } return Optional.empty(); } /** * Returns an Optional containing the first non-empty CharSequence from the given Iterable of CharSequences. * If all CharSequences are empty or the Iterable is empty, returns an empty Optional. * * @param the type of the CharSequence * @param css the Iterable of CharSequences to check, may be {@code null} or empty * @return an Optional containing the first non-empty CharSequence, or an empty Optional if all are empty or the Iterable is empty * @see Strings#firstNonEmpty(Iterable) */ public static Optional firstNonEmpty(final Iterable css) { if (isEmpty(css)) { return Optional.empty(); } for (final T e : css) { if (Strings.isNotEmpty(e)) { return Optional.of(e); } } return Optional.empty(); } /** * Returns the first non-blank CharSequence from the given CharSequences. * If both CharSequences are blank or {@code null}, it returns an empty Optional. * * @param the type of the CharSequences * @param a the first CharSequence to check * @param b the second CharSequence to check * @return an Optional containing the first non-blank CharSequence, or an empty Optional if both CharSequences are blank or null * @see Strings#firstNonBlank(CharSequence, CharSequence) */ public static Optional firstNonBlank(final T a, final T b) { return Strings.isNotBlank(a) ? Optional.of(a) : (Strings.isNotBlank(b) ? Optional.of(b) : Optional.empty()); } /** * Returns the first non-blank CharSequence from the given CharSequences. * If all CharSequences are blank or {@code null}, it returns an empty Optional. * * @param the type of the CharSequences * @param a the first CharSequence to check * @param b the second CharSequence to check * @param c the third CharSequence to check * @return an Optional containing the first non-blank CharSequence, or an empty Optional if all CharSequences are blank or null * @see Strings#firstNonBlank(CharSequence, CharSequence, CharSequence) */ public static Optional firstNonBlank(final T a, final T b, final T c) { return Strings.isNotBlank(a) ? Optional.of(a) : (Strings.isNotBlank(b) ? Optional.of(b) : (Strings.isNotBlank(c) ? Optional.of(c) : Optional.empty())); } /** * Returns the first non-blank CharSequence from the given CharSequences. * If all CharSequences are blank or {@code null}, it returns an empty Optional. * * @param the type of the CharSequences * @param a the array of CharSequences to check * @return an Optional containing the first non-blank CharSequence, or an empty Optional if all CharSequences are blank or null * @see Strings#firstNonBlank(CharSequence...) */ @SafeVarargs public static Optional firstNonBlank(final T... a) { if (isEmpty(a)) { return Optional.empty(); } for (final T e : a) { if (Strings.isNotBlank(e)) { return Optional.of(e); } } return Optional.empty(); } /** * Returns an Optional containing the first non-blank CharSequence from the given Iterable of CharSequences. * If all CharSequences are blank or the Iterable is empty, returns an empty Optional. * * @param the type of the CharSequence * @param css the Iterable of CharSequences to check, may be {@code null} or empty * @return an Optional containing the first non-blank CharSequence, or an empty Optional if all are blank or the Iterable is empty * @see Strings#firstNonBlank(Iterable) */ public static Optional firstNonBlank(final Iterable css) { if (isEmpty(css)) { return Optional.empty(); } for (final T e : css) { if (Strings.isNotBlank(e)) { return Optional.of(e); } } return Optional.empty(); } /** * Returns the first entry from the given map. * If the map is {@code null} or empty, it returns an empty Optional. * * @param the type of keys maintained by the map * @param the type of mapped values * @param map the map from which to retrieve the first entry * @return an Optional containing the first entry of the map, or an empty Optional if the map is {@code null} or empty */ public static Optional> firstEntry(final Map map) { if (map == null || map.isEmpty()) { return Optional.empty(); } return Optional.of(map.entrySet().iterator().next()); } /** * Returns the last entry from the given map. * If the map is {@code null} or empty, it returns an empty Optional. * * @param the type of keys maintained by the map * @param the type of mapped values * @param map the map from which to retrieve the last entry * @return an Optional containing the last entry of the map, or an empty Optional if the map is {@code null} or empty */ public static Optional> lastEntry(final Map map) { if (map == null || map.isEmpty()) { return Optional.empty(); } return lastNonNull(map.entrySet().iterator()); } /** * Returns the first element of the given array if it is not empty, otherwise returns {@code null}. * * @param the type of the elements in the array * @param a the array to check * @return the first element of the array if it is not empty, otherwise null */ public static T firstOrNullIfEmpty(final T[] a) { return a == null || a.length == 0 ? null : a[0]; } /** * Returns the first element of the given iterable if it is not empty, otherwise returns {@code null}. * * @param the type of the elements in the iterable * @param c the iterable to check * @return the first element of the iterable if it is not empty, otherwise null */ public static T firstOrNullIfEmpty(final Iterable c) { return firstOrDefaultIfEmpty(c, null); } /** * Returns the first element of the given iterator if it is not empty, otherwise returns {@code null}. * * @param the type of the elements in the iterator * @param iter the iterator to check * @return the first element of the iterator if it is not empty, otherwise null */ public static T firstOrNullIfEmpty(final Iterator iter) { return firstOrDefaultIfEmpty(iter, null); } /** * Returns the first element of the given array if it is not empty, otherwise returns the specified default value. * * @param the type of the elements in the array * @param a the array to check * @param defaultValueForEmpty the default value to return if the array is empty * @return the first element of the array if it is not empty, otherwise the specified default value */ public static T firstOrDefaultIfEmpty(final T[] a, final T defaultValueForEmpty) { return a == null || a.length == 0 ? defaultValueForEmpty : a[0]; } /** * Returns the first element of the given iterable if it is not empty, otherwise returns the specified default value. * * @param the type of the elements in the iterable * @param c the iterable to check * @param defaultValueForEmpty the default value to return if the iterable is empty * @return the first element of the iterable if it is not empty, otherwise the specified default value */ public static T firstOrDefaultIfEmpty(final Iterable c, final T defaultValueForEmpty) { if (isEmpty(c)) { return defaultValueForEmpty; } if (c instanceof List && c instanceof RandomAccess) { return ((List) c).get(0); } else { return c.iterator().next(); } } /** * Returns the first element of the given iterator if it is not empty, otherwise returns the specified default value. * * @param the type of the elements in the iterator * @param iter the iterator to check * @param defaultValueForEmpty the default value to return if the iterator is empty * @return the first element of the iterator if it is not empty, otherwise the specified default value */ public static T firstOrDefaultIfEmpty(final Iterator iter, final T defaultValueForEmpty) { if (iter == null || !iter.hasNext()) { return defaultValueForEmpty; } return iter.next(); } /** * Returns the last element of the given array if it is not empty, otherwise returns {@code null}. * * @param the type of the elements in the array * @param a the array to check * @return the last element of the array if it is not empty, otherwise null */ public static T lastOrNullIfEmpty(final T[] a) { return a == null || a.length == 0 ? null : a[a.length - 1]; } /** * Returns the last element of the given iterable if it is not empty, otherwise returns {@code null}. * * @param the type of the elements in the iterable * @param c the iterable to check * @return the last element of the iterable if it is not empty, otherwise null */ public static T lastOrNullIfEmpty(final Iterable c) { return lastOrDefaultIfEmpty(c, null); } /** * Returns the last element of the given iterator if it is not empty, otherwise returns {@code null}. * * @param the type of the elements in the iterator * @param iter the iterator to check * @return the last element of the iterator if it is not empty, otherwise null */ public static T lastOrNullIfEmpty(final Iterator iter) { return lastOrDefaultIfEmpty(iter, null); } /** * Returns the last element of the given array if it is not empty, otherwise returns the specified default value. * * @param the type of the elements in the array * @param a the array to check * @param defaultValueForEmpty the default value to return if the array is empty * @return the last element of the array if it is not empty, otherwise the specified default value */ public static T lastOrDefaultIfEmpty(final T[] a, final T defaultValueForEmpty) { return a == null || a.length == 0 ? defaultValueForEmpty : a[a.length - 1]; } /** * Returns the last element of the given iterable if it is not empty, otherwise returns the specified default value. * * @param the type of the elements in the iterable * @param c the iterable to check * @param defaultValueForEmpty the default value to return if the iterable is empty * @return the last element of the iterable if it is not empty, otherwise the specified default value */ public static T lastOrDefaultIfEmpty(final Iterable c, final T defaultValueForEmpty) { if (isEmpty(c)) { return defaultValueForEmpty; } if (c instanceof List && c instanceof RandomAccess) { final List list = (List) c; return list.get(list.size() - 1); } final Iterator descendingIterator = getDescendingIteratorIfPossible(c); if (descendingIterator != null) { return descendingIterator.next(); } return lastOrDefaultIfEmpty(c.iterator(), defaultValueForEmpty); } /** * Returns the last element of the given iterator if it is not empty, otherwise returns the specified default value. * * @param the type of the elements in the iterator * @param iter the iterator to check * @param defaultValueForEmpty the default value to return if the iterator is empty * @return the last element of the iterator if it is not empty, otherwise the specified default value */ public static T lastOrDefaultIfEmpty(final Iterator iter, final T defaultValueForEmpty) { if (iter == null || !iter.hasNext()) { return defaultValueForEmpty; } T e = null; while (iter.hasNext()) { e = iter.next(); } return e; } /** * Returns the first element in the given array that matches the specified predicate. * * @param the type of the elements in the array * @param a the array to search * @param predicate the predicate to apply to elements of the array * @return an Optional containing the first element that matches the predicate, or an empty Optional if no such element is found */ public static Nullable findFirst(final T[] a, final Predicate predicate) { if (isEmpty(a)) { return Nullable.empty(); } for (final T element : a) { if (predicate.test(element)) { return Nullable.of(element); } } return Nullable.empty(); } /** * Returns the first element in the given iterable that matches the specified predicate. * * @param the type of the elements in the iterable * @param c the iterable to search * @param predicate the predicate to apply to elements of the iterable * @return an Optional containing the first element that matches the predicate, or an empty Optional if no such element is found */ public static Nullable findFirst(final Iterable c, final Predicate predicate) { if (isEmpty(c)) { return Nullable.empty(); } for (final T e : c) { if (predicate.test(e)) { return Nullable.of(e); } } return Nullable.empty(); } /** * Returns the first element in the given iterator that matches the specified predicate. * * @param the type of the elements in the iterator * @param iter the iterator to search * @param predicate the predicate to apply to elements of the iterator * @return an Optional containing the first element that matches the predicate, or an empty Optional if no such element is found */ public static Nullable findFirst(final Iterator iter, final Predicate predicate) { if (iter == null) { return Nullable.empty(); } T next = null; while (iter.hasNext()) { next = iter.next(); if (predicate.test(next)) { return Nullable.of(next); } } return Nullable.empty(); } /** * Returns the last element in the given array that matches the specified predicate. * * @param the type of the elements in the array * @param a the array to search * @param predicate the predicate to apply to elements of the array * @return an Optional containing the last element that matches the predicate, or an empty Optional if no such element is found */ public static Nullable findLast(final T[] a, final Predicate predicate) { if (isEmpty(a)) { return Nullable.empty(); } for (int len = a.length, i = len - 1; i >= 0; i--) { if (predicate.test(a[i])) { return Nullable.of(a[i]); } } return Nullable.empty(); } /** * Returns the last element in the given iterable that matches the specified predicate. * * @param the type of the elements in the iterable * @param c the iterable to search * @param predicate the predicate to apply to elements of the iterable * @return an Optional containing the last element that matches the predicate, or an empty Optional if no such element is found */ public static Nullable findLast(final Iterable c, final Predicate predicate) { return (Nullable) findLast(c, predicate, false); } /** * Returns the last element in the given iterator that matches the specified predicate. * * @param the type of the elements in the iterator * @param c the iterable to search * @param predicate the predicate to apply to elements of the iterator * @return an Optional containing the last element that matches the predicate, or an empty Optional if no such element is found */ private static Object findLast(final Iterable c, final Predicate predicate, final boolean isForNonNull) { if (isEmptyCollection(c)) { return isForNonNull ? Optional.empty() : Nullable.empty(); } T e = null; if (c instanceof List && c instanceof RandomAccess) { final List list = (List) c; for (int i = list.size() - 1; i >= 0; i--) { e = list.get(i); if ((!isForNonNull || e != null) && predicate.test(e)) { return isForNonNull ? Optional.of(e) : Nullable.of(e); } } return isForNonNull ? Optional.empty() : Nullable.empty(); } final Iterator descendingIterator = getDescendingIteratorIfPossible(c); if (descendingIterator != null) { while (descendingIterator.hasNext()) { e = descendingIterator.next(); if ((!isForNonNull || e != null) && predicate.test(e)) { return isForNonNull ? Optional.of(e) : Nullable.of(e); } } return isForNonNull ? Optional.empty() : Nullable.empty(); } T[] a = null; if (c instanceof Collection) { a = (T[]) ((Collection) c).toArray(); } else { final List tmp = new ArrayList<>(); for (final T t : c) { tmp.add(t); } a = (T[]) tmp.toArray(); } for (int i = a.length - 1; i >= 0; i--) { if ((!isForNonNull || a[i] != null) && predicate.test(a[i])) { return isForNonNull ? Optional.of(a[i]) : Nullable.of(a[i]); } } return isForNonNull ? Optional.empty() : Nullable.empty(); } /** * Returns the first {@code non-null} element in the given array that matches the specified predicate. * * @param the type of the elements in the array * @param a the array to search * @param predicate the predicate to apply to elements of the array * @return an Optional containing the first {@code non-null} element that matches the predicate, or an empty Optional if no such element is found */ public static Optional findFirstNonNull(final T[] a, final Predicate predicate) { if (isEmpty(a)) { return Optional.empty(); } for (final T element : a) { if (element != null && predicate.test(element)) { return Optional.of(element); } } return Optional.empty(); } /** * Returns the first {@code non-null} element in the given iterable that matches the specified predicate. * * @param the type of the elements in the iterable * @param c the iterable to search * @param predicate the predicate to apply to elements of the iterable * @return an Optional containing the first {@code non-null} element that matches the predicate, or an empty Optional if no such element is found */ public static Optional findFirstNonNull(final Iterable c, final Predicate predicate) { if (isEmpty(c)) { return Optional.empty(); } for (final T e : c) { if (e != null && predicate.test(e)) { return Optional.of(e); } } return Optional.empty(); } /** * Returns the first {@code non-null} element in the given iterator that matches the specified predicate. * * @param the type of the elements in the iterator * @param iter the iterator to search * @param predicate the predicate to apply to elements of the iterator * @return an Optional containing the first {@code non-null} element that matches the predicate, or an empty Optional if no such element is found */ public static Optional findFirstNonNull(final Iterator iter, final Predicate predicate) { if (iter == null) { return Optional.empty(); } T next = null; while (iter.hasNext()) { next = iter.next(); if (next != null && predicate.test(next)) { return Optional.of(next); } } return Optional.empty(); } /** * Returns the last {@code non-null} element in the given array that matches the specified predicate. * * @param the type of the elements in the array * @param a the array to search * @param predicate the predicate to apply to elements of the array * @return an Optional containing the last {@code non-null} element that matches the predicate, or an empty Optional if no such element is found */ public static Optional findLastNonNull(final T[] a, final Predicate predicate) { if (isEmpty(a)) { return Optional.empty(); } for (int len = a.length, i = len - 1; i >= 0; i--) { if (a[i] != null && predicate.test(a[i])) { return Optional.of(a[i]); } } return Optional.empty(); } /** * Returns the last {@code non-null} element in the given iterable that matches the specified predicate. * * @param the type of the elements in the iterable * @param c the iterable to search * @param predicate the predicate to apply to elements of the iterable * @return an Optional containing the last {@code non-null} element that matches the predicate, or an empty Optional if no such element is found */ public static Optional findLastNonNull(final Iterable c, final Predicate predicate) { return (Optional) findLast(c, predicate, true); } /** * Returns the length of the specified {@code CharSequence}, or {@code 0} if it's empty or {@code null}. * * @param s the CharSequence to check * @return the length of the CharSequence, or 0 if the CharSequence is null */ public static int len(final CharSequence s) { return s == null ? 0 : s.length(); } /** * Returns the length/size of the specified {@code Array/Collection/Map}, or {@code 0} if it's empty or {@code null}. * * @param a the array to check * @return the length of the array, or 0 if the array is null */ public static int len(final boolean[] a) { return a == null ? 0 : a.length; } /** * Returns the length/size of the specified {@code Array/Collection/Map}, or {@code 0} if it's empty or {@code null}. * * @param a the array to check * @return the length of the array, or 0 if the array is null */ public static int len(final char[] a) { return a == null ? 0 : a.length; } /** * Returns the length/size of the specified {@code Array/Collection/Map}, or {@code 0} if it's empty or {@code null}. * * @param a the array to check * @return the length of the array, or 0 if the array is null */ public static int len(final byte[] a) { return a == null ? 0 : a.length; } /** * Returns the length/size of the specified {@code Array/Collection/Map}, or {@code 0} if it's empty or {@code null}. * * @param a the array to check * @return the length of the array, or 0 if the array is null */ public static int len(final short[] a) { return a == null ? 0 : a.length; } /** * Returns the length/size of the specified {@code Array/Collection/Map}, or {@code 0} if it's empty or {@code null}. * * @param a the array to check * @return the length of the array, or 0 if the array is null */ public static int len(final int[] a) { return a == null ? 0 : a.length; } /** * Returns the length/size of the specified {@code Array/Collection/Map}, or {@code 0} if it's empty or {@code null}. * * @param a the array to check * @return the length of the array, or 0 if the array is null */ public static int len(final long[] a) { return a == null ? 0 : a.length; } /** * Returns the length/size of the specified {@code Array/Collection/Map}, or {@code 0} if it's empty or {@code null}. * * @param a the array to check * @return the length of the array, or 0 if the array is null */ public static int len(final float[] a) { return a == null ? 0 : a.length; } /** * Returns the length/size of the specified {@code Array/Collection/Map}, or {@code 0} if it's empty or {@code null}. * * @param a the array to check * @return the length of the array, or 0 if the array is null */ public static int len(final double[] a) { return a == null ? 0 : a.length; } /** * Returns the length/size of the specified {@code Array/Collection/Map}, or {@code 0} if it's empty or {@code null}. * * @param a the array to check * @return the length of the array, or 0 if the array is null */ public static int len(final Object[] a) { return a == null ? 0 : a.length; } /** * Returns the length/size of the specified {@code Array/Collection/Map}, or {@code 0} if it's empty or {@code null}. * * @param c the collection to check * @return the size of the specified collection, or 0 if the collection is null */ public static int size(final Collection c) { return c == null ? 0 : c.size(); } /** * Returns the length/size of the specified {@code Array/Collection/Map}, or {@code 0} if it's empty or {@code null}. * * @param m the map to check * @return the size of the specified map, or 0 if the map is null */ public static int size(final Map m) { return m == null ? 0 : m.size(); } /** * Returns the length/size of the specified {@code Array/Collection/Map}, or {@code 0} if it's empty or {@code null}. * * @param c the PrimitiveList to check * @return the size of the specified PrimitiveList, or 0 if the PrimitiveList is null */ @Beta @SuppressWarnings("rawtypes") public static int size(final PrimitiveList c) { return c == null ? 0 : c.size(); } /** * Converts a {@code null} string to an empty string. * * @param str the string to check * @return the original string if it is not {@code null}, otherwise an empty string * @see Strings#nullToEmpty(String) * @see Strings#blankToEmpty(String) */ @Beta public static String nullToEmpty(final String str) { return str == null ? Strings.EMPTY : str; } /** * Returns an immutable/unmodifiable empty list if the specified list is {@code null}, otherwise itself is returned. * * @param the type of elements in the list * @param list the list to check * @return an empty list if the specified list is {@code null}, otherwise the original list * @see #emptyList() */ public static List nullToEmpty(final List list) { return list == null ? emptyList() : list; } /** * Returns an immutable/unmodifiable empty set if the specified Set is {@code null}, otherwise itself is returned. * * @param the type of elements in the set * @param set the set to check * @return an empty set if the specified set is {@code null}, otherwise the original set * @see #emptySet() */ public static Set nullToEmpty(final Set set) { return set == null ? emptySet() : set; } /** * Returns an immutable/unmodifiable empty {@code SortedSet} if the specified SortedSet is {@code null}, otherwise itself is returned. * * @param the type of elements in the set * @param set the set to check * @return an empty {@code SortedSet} if the specified set is {@code null}, otherwise the original set * @see #emptySortedSet() */ public static SortedSet nullToEmpty(final SortedSet set) { return set == null ? emptySortedSet() : set; } /** * Returns an immutable/unmodifiable empty {@code NavigableSet} if the specified NavigableSet is {@code null}, otherwise itself is returned. * * @param the type of elements in the set * @param set the set to check * @return an empty {@code NavigableSet} if the specified set is {@code null}, otherwise the original set * @see #emptyNavigableSet() */ public static NavigableSet nullToEmpty(final NavigableSet set) { return set == null ? emptyNavigableSet() : set; } /** * Returns an immutable/unmodifiable empty {@code List} if the specified list is {@code null}, otherwise itself is returned. * * @param the type of elements in the list * @param c the collection to check * @return an empty {@code List} if the specified list is {@code null}, otherwise the original list * @see #emptyList() */ public static Collection nullToEmpty(final Collection c) { return c == null ? emptyList() : c; } /** * Returns an immutable/unmodifiable empty map if the specified Map is {@code null}, otherwise itself is returned. * This method can be also used to get keySet, values, entrySet, etc. from a map *

{@code nullToEmpty(map).keySet()}

*

{@code nullToEmpty(map).values()}

*

{@code nullToEmpty(map).entrySet()}

* * @param the key type * @param the value type * @param map the map to check * @return an empty map if the specified map is {@code null}, otherwise the original map * @see #emptyMap() */ public static Map nullToEmpty(final Map map) { return map == null ? emptyMap() : map; } /** * Returns an immutable/unmodifiable empty {@code SortedMap} if the specified SortedMap is {@code null}, otherwise itself is returned. * * @param the key type * @param the value type * @param map the SortedMap to check * @return an empty {@code SortedMap} if the specified SortedMap is {@code null}, otherwise the original SortedMap * @see #emptySortedMap() */ public static SortedMap nullToEmpty(final SortedMap map) { return map == null ? emptySortedMap() : map; } /** * Returns an immutable/unmodifiable empty {@code NavigableMap} if the specified NavigableMap is {@code null}, otherwise itself is returned. * * @param the key type * @param the value type * @param map the NavigableMap to check * @return an empty {@code NavigableMap} if the specified NavigableMap is {@code null}, otherwise the original NavigableMap * @see #emptyNavigableMap() */ public static NavigableMap nullToEmpty(final NavigableMap map) { return map == null ? emptyNavigableMap() : map; } /** * Returns an immutable/unmodifiable empty iterator if the specified Iterator is {@code null}, otherwise itself is returned. * * @param the type of elements returned by this iterator * @param iter the iterator to check * @return an empty iterator if the specified Iterator is {@code null}, otherwise the original Iterator * @see #emptyIterator() */ public static Iterator nullToEmpty(final Iterator iter) { return iter == null ? emptyIterator() : iter; } /** * Returns an immutable/unmodifiable empty {@code ListIterator} if the specified ListIterator is {@code null}, otherwise itself is returned. * * @param the type of elements returned by this list iterator * @param iter the list iterator to check * @return an empty {@code ListIterator} if the specified ListIterator is {@code null}, otherwise the original ListIterator * @see #emptyListIterator() */ public static ListIterator nullToEmpty(final ListIterator iter) { return iter == null ? emptyListIterator() : iter; } /** * Returns an empty boolean array if the specified array is {@code null}, otherwise returns the original array. * * @param a the boolean array to check * @return an empty boolean array if the specified array is {@code null}, otherwise the original array */ public static boolean[] nullToEmpty(final boolean[] a) { return a == null ? EMPTY_BOOLEAN_ARRAY : a; } /** * Returns an empty char array if the specified array is {@code null}, otherwise returns the original array. * * @param a the char array to check * @return an empty char array if the specified array is {@code null}, otherwise the original array */ public static char[] nullToEmpty(final char[] a) { return a == null ? EMPTY_CHAR_ARRAY : a; } /** * Returns an empty byte array if the specified array is {@code null}, otherwise returns the original array. * * @param a the byte array to check * @return an empty byte array if the specified array is {@code null}, otherwise the original array */ public static byte[] nullToEmpty(final byte[] a) { return a == null ? EMPTY_BYTE_ARRAY : a; } /** * Returns an empty short array if the specified array is {@code null}, otherwise returns the original array. * * @param a the short array to check * @return an empty short array if the specified array is {@code null}, otherwise the original array */ public static short[] nullToEmpty(final short[] a) { return a == null ? EMPTY_SHORT_ARRAY : a; } /** * Returns an empty int array if the specified array is {@code null}, otherwise returns the original array. * * @param a the int array to check * @return an empty int array if the specified array is {@code null}, otherwise the original array */ public static int[] nullToEmpty(final int[] a) { return a == null ? EMPTY_INT_ARRAY : a; } /** * Returns an empty long array if the specified array is {@code null}, otherwise returns the original array. * * @param a the long array to check * @return an empty long array if the specified array is {@code null}, otherwise the original array */ public static long[] nullToEmpty(final long[] a) { return a == null ? EMPTY_LONG_ARRAY : a; } /** * Returns an empty float array if the specified array is {@code null}, otherwise returns the original array. * * @param a the float array to check * @return an empty float array if the specified array is {@code null}, otherwise the original array */ public static float[] nullToEmpty(final float[] a) { return a == null ? EMPTY_FLOAT_ARRAY : a; } /** * Returns an empty double array if the specified array is {@code null}, otherwise returns the original array. * * @param a the double array to check * @return an empty double array if the specified array is {@code null}, otherwise the original array */ public static double[] nullToEmpty(final double[] a) { return a == null ? EMPTY_DOUBLE_ARRAY : a; } /** * Returns an empty BigInteger array if the specified array is {@code null}, otherwise returns the original array. * * @param a the BigInteger array to check * @return an empty BigInteger array if the specified array is {@code null}, otherwise the original array */ public static BigInteger[] nullToEmpty(final BigInteger[] a) { return a == null ? EMPTY_BIG_INTEGER_ARRAY : a; } /** * Returns an empty BigDecimal array if the specified array is {@code null}, otherwise returns the original array. * * @param a the BigDecimal array to check * @return an empty BigDecimal array if the specified array is {@code null}, otherwise the original array */ public static BigDecimal[] nullToEmpty(final BigDecimal[] a) { return a == null ? EMPTY_BIG_DECIMAL_ARRAY : a; } /** * Returns an empty String array if the specified array is {@code null}, otherwise returns the original array. * * @param a the String array to check * @return an empty String array if the specified array is {@code null}, otherwise the original array * @see Strings#nullToEmpty(String) * @see Strings#nullToEmpty(String[]) */ public static String[] nullToEmpty(final String[] a) { // if (a == null) { // return EMPTY_STRING_ARRAY; // } // // for (int i = 0, len = a.length; i < len; i++) { // a[i] = a[i] == null ? Strings.EMPTY : a[i]; // } // // return a; return a == null ? EMPTY_STRING_ARRAY : a; } /** * Converts the specified String array to an empty {@code String[0]} if it's {@code null} and each {@code null} element String to empty String {@code ""}. * * @param a the String array to check * @return an empty String array if the specified array is {@code null}, otherwise the original array with each {@code null} element replaced by an empty string * @see Strings#nullToEmpty(String) * @see Strings#nullToEmpty(String[]) */ @Beta public static String[] nullToEmptyForEach(final String[] a) { // nullToEmptyForAll is better? if (a == null) { return EMPTY_STRING_ARRAY; } for (int i = 0, len = a.length; i < len; i++) { a[i] = a[i] == null ? Strings.EMPTY : a[i]; } return a; } // /** // * Converts the specified String array to an empty {@code String[0]} if it's {@code null} and each {@code null} element String to empty String {@code ""}. // * // * @param a // * @return // * @see Strings#nullToEmpty(String) // * @see Strings#nullToEmpty(String[]) // */ // static String[] nullToEmptyForAll(final String[] a) { // nullToEmptyForAll is better? // If (a == null) { // return EMPTY_STRING_ARRAY; // } // // for (int i = 0, len = a.length; i < len; i++) { // a[i] = a[i] == null ? Strings.EMPTY : a[i]; // } // // return a; // } /** * Returns an empty Date array if the specified array is {@code null}, otherwise returns the original array. * * @param a the Date array to check * @return an empty Date array if the specified array is {@code null}, otherwise the original array */ public static java.util.Date[] nullToEmpty(final java.util.Date[] a) { return a == null ? EMPTY_JU_DATE_ARRAY : a; } /** * Returns an empty Date array if the specified array is {@code null}, otherwise returns the original array. * * @param a the Date array to check * @return an empty Date array if the specified array is {@code null}, otherwise the original array */ public static java.sql.Date[] nullToEmpty(final java.sql.Date[] a) { return a == null ? EMPTY_DATE_ARRAY : a; } /** * Returns an empty Time array if the specified array is {@code null}, otherwise returns the original array. * * @param a the Time array to check * @return an empty Time array if the specified array is {@code null}, otherwise the original array */ public static java.sql.Time[] nullToEmpty(final java.sql.Time[] a) { return a == null ? EMPTY_TIME_ARRAY : a; } /** * Returns an empty Timestamp array if the specified array is {@code null}, otherwise returns the original array. * * @param a the Timestamp array to check * @return an empty Timestamp array if the specified array is {@code null}, otherwise the original array */ public static java.sql.Timestamp[] nullToEmpty(final java.sql.Timestamp[] a) { return a == null ? EMPTY_TIMESTAMP_ARRAY : a; } /** * Returns an empty Calendar array if the specified array is {@code null}, otherwise returns the original array. * * @param a the Calendar array to check * @return an empty Calendar array if the specified array is {@code null}, otherwise the original array */ public static Calendar[] nullToEmpty(final Calendar[] a) { return a == null ? EMPTY_CALENDAR_ARRAY : a; } /** * Returns an empty Object array if the specified array is {@code null}, otherwise returns the original array. * * @param a the Object array to check * @return an empty Object array if the specified array is {@code null}, otherwise the original array */ public static Object[] nullToEmpty(final Object[] a) { return a == null ? EMPTY_OBJECT_ARRAY : a; } /** * Returns an empty array of the specified type if the given array is {@code null}, otherwise returns the original array. * * @param the component type of the array * @param a the array to check * @param arrayType the class of the array type * @return an empty array of the specified type if the given array is {@code null}, otherwise the original array */ public static T[] nullToEmpty(final T[] a, final Class arrayType) { return a == null ? (T[]) newArray(arrayType.getComponentType(), 0) : a; } /** * Returns an immutable/unmodifiable empty Collection if the specified ImmutableCollection is {@code null}, otherwise itself is returned. * * @param the type of elements in the collection * @param c the ImmutableCollection to check * @return an empty ImmutableCollection if the specified collection is {@code null}, otherwise the original collection */ public static ImmutableCollection nullToEmpty(final ImmutableCollection c) { return c == null ? ImmutableList.empty() : c; } /** * Returns an immutable/unmodifiable empty list if the specified ImmutableList is {@code null}, otherwise returns the original list. * * @param the type of elements in the list * @param list the ImmutableList to check * @return an empty ImmutableList if the specified list is {@code null}, otherwise the original list */ public static ImmutableList nullToEmpty(final ImmutableList list) { return list == null ? ImmutableList.empty() : list; } /** * Returns an immutable/unmodifiable empty set if the specified ImmutableSet is {@code null}, otherwise returns the original set. * * @param the type of elements in the set * @param set the ImmutableSet to check * @return an empty ImmutableSet if the specified set is {@code null}, otherwise the original set */ public static ImmutableSet nullToEmpty(final ImmutableSet set) { return set == null ? ImmutableSet.empty() : set; } /** * Returns an immutable/unmodifiable empty sorted set if the specified ImmutableSortedSet is {@code null}, otherwise returns the original set. * * @param the type of elements in the set * @param set the ImmutableSortedSet to check * @return an empty ImmutableSortedSet if the specified set is {@code null}, otherwise the original set */ public static ImmutableSortedSet nullToEmpty(final ImmutableSortedSet set) { return set == null ? ImmutableSortedSet.empty() : set; } /** * Returns an immutable/unmodifiable empty navigable set if the specified ImmutableNavigableSet is {@code null}, otherwise returns the original set. * * @param the type of elements in the set * @param set the ImmutableNavigableSet to check * @return an empty ImmutableNavigableSet if the specified set is {@code null}, otherwise the original set */ public static ImmutableNavigableSet nullToEmpty(final ImmutableNavigableSet set) { return set == null ? ImmutableNavigableSet.empty() : set; } /** * Returns an immutable/unmodifiable empty map if the specified ImmutableMap is {@code null}, otherwise returns the original map. * * @param the type of keys in the map * @param the type of values in the map * @param map the ImmutableMap to check * @return an empty ImmutableMap if the specified map is {@code null}, otherwise the original map */ public static ImmutableMap nullToEmpty(final ImmutableMap map) { return map == null ? ImmutableMap.empty() : map; } /** * Returns an immutable/unmodifiable empty sorted map if the specified ImmutableSortedMap is {@code null}, otherwise returns the original map. * * @param the type of keys in the map * @param the type of values in the map * @param map the ImmutableSortedMap to check * @return an empty ImmutableSortedMap if the specified map is {@code null}, otherwise the original map */ public static ImmutableSortedMap nullToEmpty(final ImmutableSortedMap map) { return map == null ? ImmutableSortedMap.empty() : map; } /** * Returns an immutable/unmodifiable empty navigable map if the specified ImmutableNavigableMap is {@code null}, otherwise returns the original map. * * @param the type of keys in the map * @param the type of values in the map * @param map the ImmutableNavigableMap to check * @return an empty ImmutableNavigableMap if the specified map is {@code null}, otherwise the original map */ public static ImmutableNavigableMap nullToEmpty(final ImmutableNavigableMap map) { return map == null ? ImmutableNavigableMap.empty() : map; } /** * Returns an immutable/unmodifiable empty bi-map if the specified ImmutableBiMap is {@code null}, otherwise returns the original bi-map. * * @param the type of keys in the bi-map * @param the type of values in the bi-map * @param map the ImmutableBiMap to check * @return an empty ImmutableBiMap if the specified bi-map is {@code null}, otherwise the original bi-map */ public static ImmutableBiMap nullToEmpty(final ImmutableBiMap map) { return map == null ? ImmutableBiMap.empty() : map; } // /** // * Checks if is null or default. {@code null} is default value for all reference types, {@code false} is default value for primitive boolean, {@code 0} is the default value for primitive number type. // * // * @param s // * @return true, if is null or default // * @deprecated internal only // */ // @Deprecated // @Internal // @Beta // static boolean isNullOrDefault(final Object value) { // return (value == null) || equals(value, defaultValueOf(value.getClass())); // } /** * Checks if the specified {@code CharSequence} is {@code null} or empty. * * @param cs the CharSequence to check * @return {@code true} if the CharSequence is {@code null} or empty, otherwise {@code false} */ public static boolean isEmpty(final CharSequence cs) { return (cs == null) || (cs.isEmpty()); } /** * Checks if the specified boolean array is {@code null} or empty. * * @param a the boolean array to check * @return {@code true} if the boolean array is {@code null} or empty, otherwise false */ public static boolean isEmpty(final boolean[] a) { return (a == null) || (a.length == 0); } /** * Checks if the specified char array is {@code null} or empty. * * @param a the char array to check * @return {@code true} if the char array is {@code null} or empty, otherwise false */ public static boolean isEmpty(final char[] a) { return (a == null) || (a.length == 0); } /** * Checks if the specified byte array is {@code null} or empty. * * @param a the byte array to check * @return {@code true} if the byte array is {@code null} or empty, otherwise false */ public static boolean isEmpty(final byte[] a) { return (a == null) || (a.length == 0); } /** * Checks if the specified short array is {@code null} or empty. * * @param a the short array to check * @return {@code true} if the short array is {@code null} or empty, otherwise false */ public static boolean isEmpty(final short[] a) { return (a == null) || (a.length == 0); } /** * Checks if the specified int array is {@code null} or empty. * * @param a the int array to check * @return {@code true} if the int array is {@code null} or empty, otherwise false */ public static boolean isEmpty(final int[] a) { return (a == null) || (a.length == 0); } /** * Checks if the specified long array is {@code null} or empty. * * @param a the long array to check * @return {@code true} if the long array is {@code null} or empty, otherwise false */ public static boolean isEmpty(final long[] a) { return (a == null) || (a.length == 0); } /** * Checks if the specified float array is {@code null} or empty. * * @param a the float array to check * @return {@code true} if the float array is {@code null} or empty, otherwise false */ public static boolean isEmpty(final float[] a) { return (a == null) || (a.length == 0); } /** * Checks if the specified double array is {@code null} or empty. * * @param a the double array to check * @return {@code true} if the double array is {@code null} or empty, otherwise false */ public static boolean isEmpty(final double[] a) { return (a == null) || (a.length == 0); } /** * Checks if the specified object array is {@code null} or empty. * * @param a the object array to check * @return {@code true} if the object array is {@code null} or empty, otherwise false */ public static boolean isEmpty(final Object[] a) { return (a == null) || (a.length == 0); } /** * Checks if the specified {@code Collection} is {@code null} or empty. * * @param c the Collection to check * @return {@code true} if the Collection is {@code null} or empty, otherwise {@code false} */ public static boolean isEmpty(final Collection c) { return (c == null) || (c.isEmpty()); } /** * Checks if the specified iterable is {@code null} or empty. * * @param c the Iterable to check * @return {@code true} if the Iterable is {@code null} or empty, otherwise {@code false} */ @Beta public static boolean isEmpty(final Iterable c) { if (c == null) { return true; } if (c instanceof Collection coll) { return coll.isEmpty(); } else { return isEmpty(c.iterator()); } } /** * Checks if the specified iterable is a {@code null} or empty collection. * * @param c the iterable to check * @return {@code true} if the specified iterable is a {@code null} or empty collection, otherwise {@code false} */ static boolean isEmptyCollection(final Iterable c) { if (c == null) { return true; } if (c instanceof Collection) { return isEmpty((Collection) c); } return false; } /** * Checks if the specified iterator is {@code null} or empty. * * @param iter the Iterator to check * @return {@code true} if the Iterator is {@code null} or empty, otherwise {@code false} */ @Beta public static boolean isEmpty(final Iterator iter) { return iter == null || (!iter.hasNext()); } /** * Checks if the specified {@code Map} is {@code null} or empty. * * @param m the Map to check * @return {@code true} if the Map is {@code null} or empty, otherwise {@code false} */ public static boolean isEmpty(final Map m) { return (m == null) || (m.isEmpty()); } /** * Checks if the specified {@code PrimitiveList} is {@code null} or empty. * * @param list the PrimitiveList to check * @return {@code true} if the PrimitiveList is {@code null} or empty, otherwise {@code false} */ @SuppressWarnings("rawtypes") public static boolean isEmpty(final PrimitiveList list) { return (list == null) || (list.isEmpty()); } /** * Checks if the specified {@code Multiset} is {@code null} or empty. * * @param s the Multiset to check * @return {@code true} if the Multiset is {@code null} or empty, otherwise {@code false} */ public static boolean isEmpty(final Multiset s) { return (s == null) || (s.isEmpty()); } /** * Checks if the specified {@code Multimap} is {@code null} or empty. * * @param m the Multimap to check * @return {@code true} if the Multimap is {@code null} or empty, otherwise {@code false} */ public static boolean isEmpty(final Multimap m) { return (m == null) || (m.isEmpty()); } /** * Checks if the specified {@code DataSet} is {@code null} or empty. * * @param ds the DataSet to check * @return {@code true} if the DataSet is {@code null} or empty, otherwise {@code false} */ public static boolean isEmpty(final DataSet ds) { return (ds == null) || (ds.isEmpty()); } /** * Checks if the specified {@code CharSequence} is {@code null}, empty, or contains only whitespace characters. * * @param cs the CharSequence to check * @return {@code true} if the CharSequence is {@code null}, empty, or contains only whitespace characters, otherwise {@code false} * @see Strings#isBlank(CharSequence) */ public static boolean isBlank(final CharSequence cs) { if (isEmpty(cs)) { return true; } for (int i = 0, len = cs.length(); i < len; i++) { if (!Character.isWhitespace(cs.charAt(i))) { return false; } } return true; } /** * Checks if the specified {@code CharSequence} is not {@code null} and not empty. * * @param cs the CharSequence to check * @return {@code true} if the CharSequence is not {@code null} and not empty, otherwise {@code false} * @see Strings#isNotEmpty(CharSequence) */ public static boolean notEmpty(final CharSequence cs) { return (cs != null) && (!cs.isEmpty()); } /** * Checks if the specified boolean array is not {@code null} and not empty. * * @param a the boolean array to check * @return {@code true} if the boolean array is not {@code null} and not empty, otherwise {@code false} */ public static boolean notEmpty(final boolean[] a) { return (a != null) && (a.length > 0); } /** * Checks if the specified char array is not {@code null} and not empty. * * @param a the char array to check * @return {@code true} if the char array is not {@code null} and not empty, otherwise {@code false} */ public static boolean notEmpty(final char[] a) { return (a != null) && (a.length > 0); } /** * Checks if the specified byte array is not {@code null} and not empty. * * @param a the byte array to check * @return {@code true} if the byte array is not {@code null} and not empty, otherwise {@code false} */ public static boolean notEmpty(final byte[] a) { return (a != null) && (a.length > 0); } /** * Checks if the specified short array is not {@code null} and not empty. * * @param a the short array to check * @return {@code true} if the short array is not {@code null} and not empty, otherwise {@code false} */ public static boolean notEmpty(final short[] a) { return (a != null) && (a.length > 0); } /** * Checks if the specified int array is not {@code null} and not empty. * * @param a the int array to check * @return {@code true} if the int array is not {@code null} and not empty, otherwise {@code false} */ public static boolean notEmpty(final int[] a) { return (a != null) && (a.length > 0); } /** * Checks if the specified long array is not {@code null} and not empty. * * @param a the long array to check * @return {@code true} if the long array is not {@code null} and not empty, otherwise {@code false} */ public static boolean notEmpty(final long[] a) { return (a != null) && (a.length > 0); } /** * Checks if the specified float array is not {@code null} and not empty. * * @param a the float array to check * @return {@code true} if the float array is not {@code null} and not empty, otherwise {@code false} */ public static boolean notEmpty(final float[] a) { return (a != null) && (a.length > 0); } /** * Checks if the specified double array is not {@code null} and not empty. * * @param a the double array to check * @return {@code true} if the double array is not {@code null} and not empty, otherwise {@code false} */ public static boolean notEmpty(final double[] a) { return (a != null) && (a.length > 0); } /** * Checks if the specified object array is not {@code null} and not empty. * * @param a the object array to check * @return {@code true} if the object array is not {@code null} and not empty, otherwise {@code false} */ public static boolean notEmpty(final Object[] a) { return (a != null) && (a.length > 0); } /** * Checks if the specified {@code Collection} is not {@code null} and not empty. * * @param c the Collection to check * @return {@code true} if the Collection is not {@code null} and not empty, otherwise {@code false} */ public static boolean notEmpty(final Collection c) { return (c != null) && (c.size() > 0); } /** * Checks if the specified iterable is not {@code null} and not empty. * * @param iter the Iterable to check * @return {@code true} if the Iterable is not {@code null} and not empty, otherwise {@code false} */ @Beta public static boolean notEmpty(final Iterable iter) { if (iter == null) { return false; } if (iter instanceof Collection) { return notEmpty((Collection) iter); } else { return notEmpty(iter.iterator()); } } /** * Checks if the specified iterator is not {@code null} and not empty. * * @param iter the Iterator to check * @return {@code true} if the Iterator is not {@code null} and not empty, otherwise {@code false} */ @Beta public static boolean notEmpty(final Iterator iter) { return (iter != null) && (iter.hasNext()); } /** * Checks if the specified {@code Map} is not {@code null} and not empty. * * @param m the Map to check * @return {@code true} if the Map is not {@code null} and not empty, otherwise {@code false} */ public static boolean notEmpty(final Map m) { return (m != null) && (!m.isEmpty()); } /** * Checks if the specified {@code PrimitiveList} is not {@code null} and not empty. * * @param list the PrimitiveList to check * @return {@code true} if the PrimitiveList is not {@code null} and not empty, otherwise {@code false} */ @SuppressWarnings("rawtypes") public static boolean notEmpty(final PrimitiveList list) { return (list != null) && (!list.isEmpty()); } /** * Checks if the specified {@code Multiset} is not {@code null} and not empty. * * @param s the Multiset to check * @return {@code true} if the Multiset is not {@code null} and not empty, otherwise {@code false} */ public static boolean notEmpty(final Multiset s) { return (s != null) && (s.size() > 0); } /** * Checks if the specified {@code Multimap} is not {@code null} and not empty. * * @param m the Multimap to check * @return {@code true} if the Multimap is not {@code null} and not empty, otherwise {@code false} */ public static boolean notEmpty(final Multimap m) { return (m != null) && (!m.isEmpty()); } /** * Checks if the specified {@code DataSet} is not {@code null} and not empty. * * @param dataSet the DataSet to check * @return {@code true} if the DataSet is not {@code null} and not empty, otherwise {@code false} */ public static boolean notEmpty(final DataSet dataSet) { return (dataSet != null) && (!dataSet.isEmpty()); } /** * Checks if the specified {@code CharSequence} is not {@code null} and not empty and not contains only whitespace characters. * * @param cs the CharSequence to check * @return {@code true} if the CharSequence is not {@code null} and not empty and not contains only whitespace characters, otherwise {@code false} * @see Strings#isNotBlank(CharSequence) */ public static boolean notBlank(final CharSequence cs) { return !isBlank(cs); } /** * Checks if it's not {@code null} or default. {@code null} is default value for all reference types, {@code false} is default value for primitive boolean, {@code 0} is the default value for primitive number type. * * * @param value * @return {@code true}, if it's not {@code null} or default * @deprecated DO NOT call the methods defined in this class. it's for internal use only. */ @Deprecated static boolean notNullOrDefault(final Object value) { return (value != null) && !equals(value, defaultValueOf(value.getClass())); } /** * Checks if any of the specified objects is {@code null}. * * @param a the first object to check * @param b the second object to check * @return {@code true} if any of the objects is {@code null}, otherwise {@code false} */ public static boolean anyNull(final Object a, final Object b) { return a == null || b == null; } /** * Checks if any of the specified objects is {@code null}. * * @param a the first object to check * @param b the second object to check * @param c the third object to check * @return {@code true} if any of the objects is {@code null}, otherwise {@code false} */ public static boolean anyNull(final Object a, final Object b, final Object c) { return a == null || b == null || c == null; } /** * Checks if any element in the specified array is {@code null}. * * @param a the array of objects to check * @return {@code true} if any element in the specified array is {@code null}, otherwise {@code false} */ public static boolean anyNull(final Object... a) { if (isEmpty(a)) { return false; } for (final Object e : a) { if (e == null) { return true; } } return false; } /** * Checks if any element in the specified collection is {@code null}. * * @param c the collection of objects to check * @return {@code true} if any element in the specified collection is {@code null}, otherwise {@code false} */ public static boolean anyNull(final Iterable c) { if (isEmpty(c)) { return false; } for (final Object e : c) { if (e == null) { return true; } } return false; } /** * Checks if any of the specified CharSequences is empty ("") or {@code null}. * * @param a the first CharSequence to check * @param b the second CharSequence to check * @return {@code true} if any of the CharSequences is empty, otherwise {@code false} * @see Strings#isAnyEmpty(CharSequence, CharSequence) */ public static boolean anyEmpty(final CharSequence a, final CharSequence b) { return isEmpty(a) || isEmpty(b); } /** * Checks if any of the specified CharSequences is empty ("") or {@code null}. * * @param a the first CharSequence to check * @param b the second CharSequence to check * @param c the third CharSequence to check * @return {@code true} if any of the CharSequences is empty, otherwise {@code false} * @see Strings#isAnyEmpty(CharSequence, CharSequence, CharSequence) */ public static boolean anyEmpty(final CharSequence a, final CharSequence b, final CharSequence c) { return isEmpty(a) || isEmpty(b) || isEmpty(c); } /** *

Checks if any of the CharSequences is empty ("") or {@code null}.

* *
     * anyEmpty((String) null)    = true
     * anyEmpty((String[]) null)  = false
     * anyEmpty(null, "foo")      = true
     * anyEmpty("", "bar")        = true
     * anyEmpty("bob", "")        = true
     * anyEmpty("  bob  ", null)  = true
     * anyEmpty(" ", "bar")       = false
     * anyEmpty("foo", "bar")     = false
     * anyEmpty(new String[]{})   = false
     * anyEmpty(new String[]{""}) = true
     * 
* * @param css the CharSequences to check, may be {@code null} or empty * @return {@code true} if any of the CharSequences are empty or null * @see Strings#isAnyEmpty(CharSequence...) */ public static boolean anyEmpty(final CharSequence... css) { return Strings.isAnyEmpty(css); } /** * Checks if any of the specified CharSequence objects in the collection is empty. * * @param css the collection of CharSequence objects to check * @return {@code true} if any of the CharSequence objects is empty, otherwise {@code false} * @see Strings#isAnyEmpty(Iterable) */ public static boolean anyEmpty(final Iterable css) { return Strings.isAnyEmpty(css); } /** * Checks if any of the specified arrays is empty. * * @param a the first array to check * @param b the second array to check * @return {@code true} if any of the arrays is empty, otherwise {@code false} */ public static boolean anyEmpty(final Object[] a, final Object[] b) { return a == null || a.length == 0 || b == null || b.length == 0; } /** * Checks if any of the specified arrays is empty. * * @param a the first array to check * @param b the second array to check * @param c the third array to check * @return {@code true} if any of the arrays is empty, otherwise {@code false} */ public static boolean anyEmpty(final Object[] a, final Object[] b, final Object[] c) { return a == null || a.length == 0 || b == null || b.length == 0 || c == null || c.length == 0; } /** * Checks if any of the specified collections is empty. * * @param a the first collection to check * @param b the second collection to check * @return {@code true} if any of the collections is empty, otherwise {@code false} */ public static boolean anyEmpty(final Collection a, final Collection b) { return a == null || a.size() == 0 || b == null || b.size() == 0; } /** * Checks if any of the specified collections is empty. * * @param a the first collection to check * @param b the second collection to check * @param c the third collection to check * @return {@code true} if any of the collections is empty, otherwise {@code false} */ public static boolean anyEmpty(final Collection a, final Collection b, final Collection c) { return a == null || a.size() == 0 || b == null || b.size() == 0 || c == null || c.size() == 0; } /** * Checks if any of the specified maps is empty. * * @param a the first map to check * @param b the second map to check * @return {@code true} if any of the maps is empty, otherwise {@code false} */ public static boolean anyEmpty(final Map a, final Map b) { return a == null || a.isEmpty() || b == null || b.isEmpty(); } /** * Checks if any of the specified maps is empty. * * @param a the first map to check * @param b the second map to check * @param c the third map to check * @return {@code true} if any of the maps is empty, otherwise {@code false} */ public static boolean anyEmpty(final Map a, final Map b, final Map c) { return a == null || a.isEmpty() || b == null || b.isEmpty() || c == null || c.isEmpty(); } /** * Checks if any of the specified CharSequences is blank. * * @param a the first CharSequence to check * @param b the second CharSequence to check * @return {@code true} if any of the CharSequences is blank, otherwise {@code false} * @see Strings#isAnyBlank(CharSequence, CharSequence) */ public static boolean anyBlank(final CharSequence a, final CharSequence b) { return isBlank(a) || isBlank(b); } /** * Checks if any of the specified CharSequences is blank. * * @param a the first CharSequence to check * @param b the second CharSequence to check * @param c the third CharSequence to check * @return {@code true} if any of the CharSequences is blank, otherwise {@code false} * @see Strings#isAnyBlank(CharSequence, CharSequence, CharSequence) */ public static boolean anyBlank(final CharSequence a, final CharSequence b, final CharSequence c) { return isBlank(a) || isBlank(b) || isBlank(c); } /** *

Checks if any of the CharSequences are empty ("") or {@code null} or whitespace only.

* *

Whitespace is defined by {@link Character#isWhitespace(char)}.

* *
     * anyBlank((String) null)    = true
     * anyBlank((String[]) null)  = false
     * anyBlank(null, "foo")      = true
     * anyBlank(null, null)       = true
     * anyBlank("", "bar")        = true
     * anyBlank("bob", "")        = true
     * anyBlank("  bob  ", null)  = true
     * anyBlank(" ", "bar")       = true
     * anyBlank(new String[] {})  = false
     * anyBlank(new String[]{""}) = true
     * anyBlank("foo", "bar")     = false
     * 
* * @param css the CharSequences to check, may be {@code null} or empty * @return {@code true} if any of the CharSequences are empty or {@code null} or whitespace only * @see Strings#isAnyBlank(CharSequence...) */ public static boolean anyBlank(final CharSequence... css) { if (isEmpty(css)) { return false; } for (final CharSequence cs : css) { if (isBlank(cs)) { return true; } } return false; } /** * Checks if any of the specified CharSequences in the collection is blank. * * @param css the collection of CharSequences to check * @return {@code true} if any of the CharSequences is blank, otherwise {@code false} * @see Strings#isAnyBlank(Iterable) */ public static boolean anyBlank(final Iterable css) { if (isEmpty(css)) { return false; } for (final CharSequence cs : css) { if (isBlank(cs)) { return true; } } return false; } /** * Checks if both specified objects are {@code null}. * * @param a the first object to check * @param b the second object to check * @return {@code true} if both objects are {@code null}, otherwise {@code false} */ public static boolean allNull(final Object a, final Object b) { return a == null && b == null; } /** * Checks if all specified objects are {@code null}. * * @param a the first object to check * @param b the second object to check * @param c the third object to check * @return {@code true} if all objects are {@code null}, otherwise {@code false} */ public static boolean allNull(final Object a, final Object b, final Object c) { return a == null && b == null && c == null; } /** * Checks if all specified objects are {@code null}. * * @param a the objects to check * @return {@code true} if all objects are {@code null}, otherwise {@code false} */ public static boolean allNull(final Object... a) { if (isEmpty(a)) { return true; } for (final Object e : a) { if (e != null) { return false; } } return true; } /** * Checks if all elements in the specified collection are {@code null}. * * @param c the collection of objects to check * @return {@code true} if all elements in the specified collection are {@code null}, otherwise {@code false} */ public static boolean allNull(final Iterable c) { if (isEmpty(c)) { return true; } for (final Object e : c) { if (e != null) { return false; } } return true; } /** * Checks if both specified CharSequences are empty ("") or {@code null}. * * @param a the first CharSequence to check * @param b the second CharSequence to check * @return {@code true} if both CharSequences are empty, otherwise {@code false} * @see Strings#isAllEmpty(CharSequence, CharSequence) */ public static boolean allEmpty(final CharSequence a, final CharSequence b) { return isEmpty(a) && isEmpty(b); } /** * Checks if all the specified CharSequences are empty ("") or {@code null}. * * @param a the first CharSequence to check * @param b the second CharSequence to check * @param c the third CharSequence to check * @return {@code true} if all the CharSequences are empty, otherwise {@code false} * @see Strings#isAllEmpty(CharSequence, CharSequence, CharSequence) */ public static boolean allEmpty(final CharSequence a, final CharSequence b, final CharSequence c) { return isEmpty(a) && isEmpty(b) && isEmpty(c); } /** *

Checks if all the CharSequences are empty ("") or {@code null}.

* *
     * allEmpty(null)             = true
     * allEmpty(null, "")         = true
     * allEmpty(new String[] {})  = true
     * allEmpty(null, "foo")      = false
     * allEmpty("", "bar")        = false
     * allEmpty("bob", "")        = false
     * allEmpty("  bob  ", null)  = false
     * allEmpty(" ", "bar")       = false
     * allEmpty("foo", "bar")     = false
     * 
* * @param css the CharSequences to check, may be {@code null} or empty * @return {@code true} if all the CharSequences are empty or null * @see Strings#isAllEmpty(CharSequence...) */ public static boolean allEmpty(final CharSequence... css) { if (isEmpty(css)) { return true; } for (final CharSequence cs : css) { if (notEmpty(cs)) { return false; } } return true; } /** * Checks if all specified CharSequences in the collection are empty or {@code null}. * * @param css the collection of CharSequences to check, may be {@code null} or empty * @return {@code true} if all CharSequences in the collection are empty or {@code null}, otherwise {@code false} */ public static boolean allEmpty(final Iterable css) { if (isEmpty(css)) { return true; } for (final CharSequence cs : css) { if (notEmpty(cs)) { return false; } } return true; } /** * Checks if all specified object arrays are empty. * * @param a the first object array to check, which may be null * @param b the second object array to check, which may be null * @return {@code true} if both object arrays are empty or {@code null}, otherwise {@code false} */ public static boolean allEmpty(final Object[] a, final Object[] b) { return isEmpty(a) && isEmpty(b); } /** * Checks if all specified object arrays are empty. * * @param a the first object array to check, which may be null * @param b the second object array to check, which may be null * @param c the third object array to check, which may be null * @return {@code true} if all object arrays are empty or {@code null}, otherwise {@code false} */ public static boolean allEmpty(final Object[] a, final Object[] b, final Object[] c) { return isEmpty(a) && isEmpty(b) && isEmpty(c); } /** * Checks if all specified collections are empty. * * @param a the first collection to check, which may be null * @param b the second collection to check, which may be null * @return {@code true} if both collections are empty or {@code null}, otherwise {@code false} */ public static boolean allEmpty(final Collection a, final Collection b) { return isEmpty(a) && isEmpty(b); } /** * Checks if all specified collections are empty. * * @param a the first collection to check, which may be null * @param b the second collection to check, which may be null * @param c the third collection to check, which may be null * @return {@code true} if all collections are empty or {@code null}, otherwise {@code false} */ public static boolean allEmpty(final Collection a, final Collection b, final Collection c) { return isEmpty(a) && isEmpty(b) && isEmpty(c); } /** * Checks if all specified maps are empty. * * @param a the first map to check, which may be null * @param b the second map to check, which may be null * @return {@code true} if both maps are empty or {@code null}, otherwise {@code false} */ public static boolean allEmpty(final Map a, final Map b) { return isEmpty(a) && isEmpty(b); } /** * Checks if all specified maps are empty. * * @param a the first map to check, which may be null * @param b the second map to check, which may be null * @param c the third map to check, which may be null * @return {@code true} if all maps are empty or {@code null}, otherwise {@code false} */ public static boolean allEmpty(final Map a, final Map b, final Map c) { return isEmpty(a) && isEmpty(b) && isEmpty(c); } /** * Checks if both specified CharSequences are blank. * * @param a the first CharSequence to check * @param b the second CharSequence to check * @return {@code true} if both CharSequences are blank, otherwise {@code false} * @see Strings#isAllBlank(CharSequence, CharSequence) */ public static boolean allBlank(final CharSequence a, final CharSequence b) { return isBlank(a) && isBlank(b); } /** * Checks if all the specified CharSequences are blank. * * @param a the first CharSequence to check * @param b the second CharSequence to check * @param c the third CharSequence to check * @return {@code true} if all the CharSequences are blank, otherwise {@code false} * @see Strings#isAllBlank(CharSequence, CharSequence, CharSequence) */ public static boolean allBlank(final CharSequence a, final CharSequence b, final CharSequence c) { return isBlank(a) && isBlank(b) && isBlank(c); } /** *

Checks if all the CharSequences are empty (""), {@code null} or whitespace only.

* *

Whitespace is defined by {@link Character#isWhitespace(char)}.

* *
     * allBlank(null)             = true
     * allBlank(null, "foo")      = false
     * allBlank(null, null)       = true
     * allBlank("", "bar")        = false
     * allBlank("bob", "")        = false
     * allBlank("  bob  ", null)  = false
     * allBlank(" ", "bar")       = false
     * allBlank("foo", "bar")     = false
     * allBlank(new String[] {})  = true
     * 
* * @param css the CharSequences to check, may be {@code null} or empty * @return {@code true} if all the CharSequences are empty or {@code null} or whitespace only * @see Strings#isAllBlank(CharSequence...) */ public static boolean allBlank(final CharSequence... css) { if (isEmpty(css)) { return true; } for (final CharSequence cs : css) { if (notBlank(cs)) { return false; } } return true; } /** * Checks if all specified CharSequences in the collection are blank. * * @param css the collection of CharSequences to check * @return {@code true} if all CharSequences in the collection are blank, otherwise {@code false} * @see Strings#isAllBlank(Iterable) */ public static boolean allBlank(final Iterable css) { if (isEmpty(css)) { return true; } for (final CharSequence cs : css) { if (notBlank(cs)) { return false; } } return true; } /** * Checks if the specified range starting from {@code fromIndex} and ending with {@code toIndex} are within the bounds of the specified length. * * @param fromIndex the starting index to check, inclusive * @param toIndex the ending index to check, exclusive * @param length the length of the array or collection * @throws IndexOutOfBoundsException if the range is out of bounds */ public static void checkFromToIndex(final int fromIndex, final int toIndex, final int length) throws IndexOutOfBoundsException { if (fromIndex < 0 || fromIndex > toIndex || toIndex > length) { throw new IndexOutOfBoundsException("Index range [" + fromIndex + ", " + toIndex + "] is out-of-bounds for length " + length); } } /** * Checks if the specified range starting from {@code fromIndex} with the specified {@code size} is within the bounds of the specified length. * * @param fromIndex the starting index to check, inclusive * @param size the size of the range to check * @param length the length of the array or collection * @throws IndexOutOfBoundsException if the range is out of bounds */ public static void checkFromIndexSize(final int fromIndex, final int size, final int length) throws IndexOutOfBoundsException { if ((fromIndex < 0 || size < 0 || length < 0) || size > length - fromIndex) { throw new IndexOutOfBoundsException("Start Index " + fromIndex + " with size " + size + " is out-of-bounds for length " + length); } } /** * Ensures that {@code index} specifies a valid element in an array, list or string of size * {@code size}. An element index may range from zero, inclusive, to {@code size}, exclusive. * * @param index a user-supplied index identifying an element of an array, list or string * @param size the size of that array, list or string * @return the value of {@code index} * @throws IndexOutOfBoundsException if {@code index} is negative or is not less than {@code size} * @throws IllegalArgumentException if {@code size} is negative * @deprecated Use {@link #checkElementIndex(int, int)} instead */ @Deprecated public static int checkIndex(final int index, final int size) { return checkElementIndex(index, size); } /** *

Copied from Google Guava under Apache License v2.0 and may be modified.

* * Ensures that {@code index} specifies a valid element in an array, list or string of size * {@code size}. An element index may range from zero, inclusive, to {@code size}, exclusive. * * @param index a user-supplied index identifying an element of an array, list or string * @param size the size of that array, list or string * @return the value of {@code index} * @throws IndexOutOfBoundsException if {@code index} is negative or is not less than {@code size} * @throws IllegalArgumentException if {@code size} is negative */ public static int checkElementIndex(final int index, final int size) { return checkElementIndex(index, size, "index"); } /** *

Copied from Google Guava under Apache License v2.0 and may be modified.

* * Ensures that {@code index} specifies a valid element in an array, list or string of size * {@code size}. An element index may range from zero, inclusive, to {@code size}, exclusive. * * @param index a user-supplied index identifying an element of an array, list or string * @param size the size of that array, list or string * @param desc the text to use to describe this index in an error message * @return the value of {@code index} * @throws IndexOutOfBoundsException if {@code index} is negative or is not less than {@code size} * @throws IllegalArgumentException if {@code size} is negative */ public static int checkElementIndex(final int index, final int size, final String desc) { // Carefully optimized for execution by hotspot (explanatory comment above) if (index < 0 || index >= size) { throw new IndexOutOfBoundsException(badElementIndex(index, size, desc)); } return index; } private static String badElementIndex(final int index, final int size, final String desc) { if (index < 0) { return Strings.lenientFormat("%s (%s) must not be negative", desc, index); } else if (size < 0) { throw new IllegalArgumentException("negative size: " + size); } else { // index >= size return Strings.lenientFormat("%s (%s) must be less than size (%s)", desc, index, size); } } /** *

Copied from Google Guava under Apache License v2.0 and may be modified.

* * Ensures that {@code index} specifies a valid position in an array, list or string of * size {@code size}. A position index may range from zero to {@code size}, inclusive. * * @param index a user-supplied index identifying a position in an array, list or string * @param size the size of that array, list or string * @return the value of {@code index} * @throws IllegalArgumentException if {@code size} is negative * @throws IndexOutOfBoundsException if {@code index} is negative or is greater than {@code size} */ @SuppressWarnings("UnusedReturnValue") public static int checkPositionIndex(final int index, final int size) throws IllegalArgumentException, IndexOutOfBoundsException { return checkPositionIndex(index, size, "index"); } /** *

Copied from Google Guava under Apache License v2.0 and may be modified.

* * Ensures that {@code index} specifies a valid position in an array, list or string of * size {@code size}. A position index may range from zero to {@code size}, inclusive. * * @param index a user-supplied index identifying a position in an array, list or string * @param size the size of that array, list or string * @param desc the text to use to describe this index in an error message * @return the value of {@code index} * @throws IllegalArgumentException if {@code size} is negative * @throws IndexOutOfBoundsException if {@code index} is negative or is greater than {@code size} */ public static int checkPositionIndex(final int index, final int size, final String desc) throws IllegalArgumentException, IndexOutOfBoundsException { // Carefully optimized for execution by hotspot (explanatory comment above) if (size < 0) { throw new IllegalArgumentException("negative size: " + size); } if (index < 0 || index > size) { throw new IndexOutOfBoundsException(badPositionIndex(index, size, desc)); } return index; } private static String badPositionIndex(final int index, final int size, final String desc) { if (index < 0) { return Strings.lenientFormat("%s (%s) must not be negative", desc, index); } else if (size < 0) { throw new IllegalArgumentException("negative size: " + size); } else { // index > size return Strings.lenientFormat("%s (%s) must not be greater than size (%s)", desc, index, size); } } /** * Checks if the specified argument is not {@code null}, and throws {@code IllegalArgumentException} if it is. * * @param the type of the argument * @param obj the argument to check * @return the {@code non-null} argument * @throws IllegalArgumentException if the argument is null */ public static T checkArgNotNull(final T obj) throws IllegalArgumentException { if (obj == null) { throw new IllegalArgumentException(); } return obj; } /** * Checks if the specified argument is not {@code null}, and throws {@code IllegalArgumentException} if it is. * * @param the type of the argument * @param obj the argument to check * @param errorMessage the error message to use in the exception * @return the {@code non-null} argument * @throws IllegalArgumentException if the argument is null */ public static T checkArgNotNull(final T obj, final String errorMessage) throws IllegalArgumentException { if (obj == null) { if (isArgNameOnly(errorMessage)) { throw new IllegalArgumentException("'" + errorMessage + "' cannot be null"); } else { throw new IllegalArgumentException(errorMessage); } } return obj; } private static boolean isArgNameOnly(final String argNameOrErrorMsg) { // shortest message: "it is null" return !(argNameOrErrorMsg.length() > 9 && argNameOrErrorMsg.indexOf(WD._SPACE) > 0); //NOSONAR } /** * Checks if the specified charSequence argument is {@code null} or empty, and throws {@code IllegalArgumentException} if it is. * * @param the type of the argument, which extends CharSequence * @param arg the argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the {@code non-null} and non-empty argument * @throws IllegalArgumentException if the argument is {@code null} or empty */ public static T checkArgNotEmpty(final T arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (Strings.isEmpty(arg)) { throwIllegalArgumentExceptionForNllOrEmptyCheck(argNameOrErrorMsg); } return arg; } /** * Checks if the specified boolean array argument is not {@code null} or empty, and throws {@code IllegalArgumentException} if it is. * * @param arg the boolean array argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the {@code non-null} and non-empty boolean array argument * @throws IllegalArgumentException if the argument is {@code null} or empty */ public static boolean[] checkArgNotEmpty(final boolean[] arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (isEmpty(arg)) { throwIllegalArgumentExceptionForNllOrEmptyCheck(argNameOrErrorMsg); } return arg; } /** * Checks if the specified char array argument is not {@code null} or empty, and throws {@code IllegalArgumentException} if it is. * * @param arg the char array argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the {@code non-null} and non-empty char array argument * @throws IllegalArgumentException if the argument is {@code null} or empty */ public static char[] checkArgNotEmpty(final char[] arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (isEmpty(arg)) { throwIllegalArgumentExceptionForNllOrEmptyCheck(argNameOrErrorMsg); } return arg; } /** * Checks if the specified byte array argument is not {@code null} or empty, and throws {@code IllegalArgumentException} if it is. * * @param arg the byte array argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the {@code non-null} and non-empty byte array argument * @throws IllegalArgumentException if the argument is {@code null} or empty */ public static byte[] checkArgNotEmpty(final byte[] arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (isEmpty(arg)) { throwIllegalArgumentExceptionForNllOrEmptyCheck(argNameOrErrorMsg); } return arg; } /** * Checks if the specified short array argument is not {@code null} or empty, and throws {@code IllegalArgumentException} if it is. * * @param arg the short array argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the {@code non-null} and non-empty short array argument * @throws IllegalArgumentException if the argument is {@code null} or empty */ public static short[] checkArgNotEmpty(final short[] arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (isEmpty(arg)) { throwIllegalArgumentExceptionForNllOrEmptyCheck(argNameOrErrorMsg); } return arg; } /** * Checks if the specified int array argument is not {@code null} or empty, and throws {@code IllegalArgumentException} if it is. * * @param arg the int array argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the {@code non-null} and non-empty int array argument * @throws IllegalArgumentException if the argument is {@code null} or empty */ public static int[] checkArgNotEmpty(final int[] arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (isEmpty(arg)) { throwIllegalArgumentExceptionForNllOrEmptyCheck(argNameOrErrorMsg); } return arg; } /** * Checks if the specified long array argument is not {@code null} or empty, and throws {@code IllegalArgumentException} if it is. * * @param arg the long array argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the {@code non-null} and non-empty long array argument * @throws IllegalArgumentException if the argument is {@code null} or empty */ public static long[] checkArgNotEmpty(final long[] arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (isEmpty(arg)) { throwIllegalArgumentExceptionForNllOrEmptyCheck(argNameOrErrorMsg); } return arg; } /** * Checks if the specified float array argument is not {@code null} or empty, and throws {@code IllegalArgumentException} if it is. * * @param arg the float array argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the {@code non-null} and non-empty float array argument * @throws IllegalArgumentException if the argument is {@code null} or empty */ public static float[] checkArgNotEmpty(final float[] arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (isEmpty(arg)) { throwIllegalArgumentExceptionForNllOrEmptyCheck(argNameOrErrorMsg); } return arg; } /** * Checks if the specified double array argument is not {@code null} or empty, and throws {@code IllegalArgumentException} if it is. * * @param arg the double array argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the {@code non-null} and non-empty double array argument * @throws IllegalArgumentException if the argument is {@code null} or empty */ public static double[] checkArgNotEmpty(final double[] arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (isEmpty(arg)) { throwIllegalArgumentExceptionForNllOrEmptyCheck(argNameOrErrorMsg); } return arg; } /** * Checks if the specified Object array argument is not {@code null} or empty, and throws {@code IllegalArgumentException} if it is. * * @param the type of the argument * @param arg the Object array argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the {@code non-null} and non-empty Object array argument * @throws IllegalArgumentException if the argument is {@code null} or empty */ public static T[] checkArgNotEmpty(final T[] arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (isEmpty(arg)) { throwIllegalArgumentExceptionForNllOrEmptyCheck(argNameOrErrorMsg); } return arg; } /** * Checks if the specified collection argument is not {@code null} or empty, and throws {@code IllegalArgumentException} if it is. * * @param arg the boolean collection argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the {@code non-null} and non-empty boolean collection argument * @throws IllegalArgumentException if the argument is {@code null} or empty */ public static > T checkArgNotEmpty(final T arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (isEmpty(arg)) { throwIllegalArgumentExceptionForNllOrEmptyCheck(argNameOrErrorMsg); } return arg; } /** * Checks if the specified Iterable argument is not {@code null} or empty, and throws {@code IllegalArgumentException} if it is. * * @param arg the Iterable argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the {@code non-null} and non-empty Iterable argument * @throws IllegalArgumentException if the argument is {@code null} or empty */ @Beta public static > T checkArgNotEmpty(final T arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (isEmpty(arg)) { throwIllegalArgumentExceptionForNllOrEmptyCheck(argNameOrErrorMsg); } return arg; } /** * Checks if the specified Iterator argument is not {@code null} or empty, and throws {@code IllegalArgumentException} if it is. * * @param arg the Iterator argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the {@code non-null} and non-empty Iterator argument * @throws IllegalArgumentException if the argument is {@code null} or empty */ @Beta public static > T checkArgNotEmpty(final T arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (isEmpty(arg)) { throwIllegalArgumentExceptionForNllOrEmptyCheck(argNameOrErrorMsg); } return arg; } /** * Checks if the specified Map argument is not {@code null} or empty, and throws {@code IllegalArgumentException} if it is. * * @param the type of the argument * @param arg the Map argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the {@code non-null} and non-empty Map argument * @throws IllegalArgumentException if the argument is {@code null} or empty */ public static > T checkArgNotEmpty(final T arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (isEmpty(arg)) { throwIllegalArgumentExceptionForNllOrEmptyCheck(argNameOrErrorMsg); } return arg; } /** * Checks if the specified PrimitiveList argument is not {@code null} or empty, and throws {@code IllegalArgumentException} if it is. * * @param the type of the argument * @param arg the PrimitiveList argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the {@code non-null} and non-empty PrimitiveList argument * @throws IllegalArgumentException if the argument is {@code null} or empty */ public static > T checkArgNotEmpty(final T arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (isEmpty(arg)) { throwIllegalArgumentExceptionForNllOrEmptyCheck(argNameOrErrorMsg); } return arg; } /** * Checks if the specified Multiset argument is not {@code null} or empty, and throws {@code IllegalArgumentException} if it is. * * @param the type of the argument * @param arg the Multiset argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the {@code non-null} and non-empty Multiset argument * @throws IllegalArgumentException if the argument is {@code null} or empty */ public static Multiset checkArgNotEmpty(final Multiset arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (isEmpty(arg)) { throwIllegalArgumentExceptionForNllOrEmptyCheck(argNameOrErrorMsg); } return arg; } /** * Checks if the specified Multimap argument is not {@code null} or empty, and throws {@code IllegalArgumentException} if it is. * * @param the type of the argument * @param arg the Multimap argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the {@code non-null} and non-empty Multimap argument * @throws IllegalArgumentException if the argument is {@code null} or empty */ public static > T checkArgNotEmpty(final T arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (isEmpty(arg)) { throwIllegalArgumentExceptionForNllOrEmptyCheck(argNameOrErrorMsg); } return arg; } /** * Checks if the specified DataSet argument is not {@code null} or empty, and throws {@code IllegalArgumentException} if it is. * * @param the type of the argument * @param arg the DataSet argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the {@code non-null} and non-empty DataSet argument * @throws IllegalArgumentException if the argument is {@code null} or empty */ public static T checkArgNotEmpty(final T arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (isEmpty(arg)) { throwIllegalArgumentExceptionForNllOrEmptyCheck(argNameOrErrorMsg); } return arg; } private static void throwIllegalArgumentExceptionForNllOrEmptyCheck(final String errorMessage) { if (isArgNameOnly(errorMessage)) { throw new IllegalArgumentException("'" + errorMessage + "' cannot be null or empty"); } else { throw new IllegalArgumentException(errorMessage); } } /** * Checks if the specified charSequence argument is not {@code null} or empty or blank, and throws {@code IllegalArgumentException} if it is. * * @param the type of the argument, which extends CharSequence * @param arg the argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the {@code non-null} and non-empty and non-blank argument * @throws IllegalArgumentException if the argument is {@code null} or empty or blank */ // DON'T change 'OrEmptyOrBlank' to 'OrBlank' because of the occurring order in the auto-completed context menu. public static T checkArgNotBlank(final T arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (Strings.isBlank(arg)) { if (isArgNameOnly(argNameOrErrorMsg)) { throw new IllegalArgumentException("'" + argNameOrErrorMsg + "' cannot be null or empty or blank"); } else { throw new IllegalArgumentException(argNameOrErrorMsg); } } return arg; } /** * Checks if the specified byte argument is not negative, and throws {@code IllegalArgumentException} if it is. * * @param arg the byte argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the non-negative byte argument * @throws IllegalArgumentException if the specified arg is negative */ public static byte checkArgNotNegative(final byte arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (arg < 0) { if (isArgNameOnly(argNameOrErrorMsg)) { throw new IllegalArgumentException("'" + argNameOrErrorMsg + "' cannot be negative: " + arg); //NOSONAR } else { throw new IllegalArgumentException(argNameOrErrorMsg); } } return arg; } /** * Checks if the specified short argument is not negative, and throws {@code IllegalArgumentException} if it is. * * @param arg the short argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the non-negative short argument * @throws IllegalArgumentException if the specified arg is negative */ public static short checkArgNotNegative(final short arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (arg < 0) { if (isArgNameOnly(argNameOrErrorMsg)) { throw new IllegalArgumentException("'" + argNameOrErrorMsg + "' cannot be negative: " + arg); //NOSONAR } else { throw new IllegalArgumentException(argNameOrErrorMsg); } } return arg; } /** * Checks if the specified int argument is not negative, and throws {@code IllegalArgumentException} if it is. * * @param arg the int argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the non-negative int argument * @throws IllegalArgumentException if the specified arg is negative */ @SuppressWarnings("UnusedReturnValue") public static int checkArgNotNegative(final int arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (arg < 0) { if (isArgNameOnly(argNameOrErrorMsg)) { throw new IllegalArgumentException("'" + argNameOrErrorMsg + "' cannot be negative: " + arg); //NOSONAR } else { throw new IllegalArgumentException(argNameOrErrorMsg); } } return arg; } /** * Checks if the specified long argument is not negative, and throws {@code IllegalArgumentException} if it is. * * @param arg the long argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the non-negative long argument * @throws IllegalArgumentException if the specified arg is negative */ @SuppressWarnings("UnusedReturnValue") public static long checkArgNotNegative(final long arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (arg < 0) { if (isArgNameOnly(argNameOrErrorMsg)) { throw new IllegalArgumentException("'" + argNameOrErrorMsg + "' cannot be negative: " + arg); } else { throw new IllegalArgumentException(argNameOrErrorMsg); } } return arg; } /** * Checks if the specified float argument is not negative, and throws {@code IllegalArgumentException} if it is. * * @param arg the float argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the non-negative float argument * @throws IllegalArgumentException if the specified arg is negative */ public static float checkArgNotNegative(final float arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (arg < 0) { if (isArgNameOnly(argNameOrErrorMsg)) { throw new IllegalArgumentException("'" + argNameOrErrorMsg + "' cannot be negative: " + arg); } else { throw new IllegalArgumentException(argNameOrErrorMsg); } } return arg; } /** * Checks if the specified double argument is not negative, and throws {@code IllegalArgumentException} if it is. * * @param arg the double argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the non-negative double argument * @throws IllegalArgumentException if the specified arg is negative */ public static double checkArgNotNegative(final double arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (arg < 0) { if (isArgNameOnly(argNameOrErrorMsg)) { throw new IllegalArgumentException("'" + argNameOrErrorMsg + "' cannot be negative: " + arg); } else { throw new IllegalArgumentException(argNameOrErrorMsg); } } return arg; } /** * Checks if the specified byte argument is positive, and throws {@code IllegalArgumentException} if it is not. * * @param arg the byte argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the positive byte argument * @throws IllegalArgumentException if the specified arg is not positive */ public static byte checkArgPositive(final byte arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (arg <= 0) { if (isArgNameOnly(argNameOrErrorMsg)) { throw new IllegalArgumentException("'" + argNameOrErrorMsg + "' cannot be zero or negative: " + arg); } else { throw new IllegalArgumentException(argNameOrErrorMsg); } } return arg; } /** * Checks if the specified short argument is positive, and throws {@code IllegalArgumentException} if it is not. * * @param arg the short argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the positive short argument * @throws IllegalArgumentException if the specified arg is not positive */ public static short checkArgPositive(final short arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (arg <= 0) { if (isArgNameOnly(argNameOrErrorMsg)) { throw new IllegalArgumentException("'" + argNameOrErrorMsg + "' cannot be zero or negative: " + arg); } else { throw new IllegalArgumentException(argNameOrErrorMsg); } } return arg; } /** * Checks if the specified int argument is positive, and throws {@code IllegalArgumentException} if it is not. * * @param arg the int argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the positive int argument * @throws IllegalArgumentException if the specified arg is not positive */ @SuppressWarnings("UnusedReturnValue") public static int checkArgPositive(final int arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (arg <= 0) { if (isArgNameOnly(argNameOrErrorMsg)) { throw new IllegalArgumentException("'" + argNameOrErrorMsg + "' cannot be zero or negative: " + arg); } else { throw new IllegalArgumentException(argNameOrErrorMsg); } } return arg; } /** * Checks if the specified long argument is positive, and throws {@code IllegalArgumentException} if it is not. * * @param arg the long argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the positive long argument * @throws IllegalArgumentException if the specified arg is not positive */ @SuppressWarnings("UnusedReturnValue") public static long checkArgPositive(final long arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (arg <= 0) { if (isArgNameOnly(argNameOrErrorMsg)) { throw new IllegalArgumentException("'" + argNameOrErrorMsg + "' cannot be zero or negative: " + arg); } else { throw new IllegalArgumentException(argNameOrErrorMsg); } } return arg; } /** * Checks if the specified float argument is positive, and throws {@code IllegalArgumentException} if it is not. * * @param arg the float argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the positive float argument * @throws IllegalArgumentException if the specified arg is not positive */ public static float checkArgPositive(final float arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (arg <= 0) { if (isArgNameOnly(argNameOrErrorMsg)) { throw new IllegalArgumentException("'" + argNameOrErrorMsg + "' cannot be zero or negative: " + arg); } else { throw new IllegalArgumentException(argNameOrErrorMsg); } } return arg; } /** * Checks if the specified double argument is positive, and throws {@code IllegalArgumentException} if it is not. * * @param arg the double argument to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @return the positive double argument * @throws IllegalArgumentException if the specified arg is not positive */ @SuppressWarnings("UnusedReturnValue") public static double checkArgPositive(final double arg, final String argNameOrErrorMsg) throws IllegalArgumentException { if (arg <= 0) { if (isArgNameOnly(argNameOrErrorMsg)) { throw new IllegalArgumentException("'" + argNameOrErrorMsg + "' cannot be zero or negative: " + arg); } else { throw new IllegalArgumentException(argNameOrErrorMsg); } } return arg; } /** * Checks if the specified array not contains any {@code null} element, and throws {@code IllegalArgumentException} if it does. * * @param a the array to check * @throws IllegalArgumentException if a {@code null} element is found in the array */ public static void checkElementNotNull(final Object[] a) throws IllegalArgumentException { if (isEmpty(a)) { return; } for (final Object e : a) { if (e == null) { throw new IllegalArgumentException("null element is found in collection"); } } } /** * Checks if the specified array not contains any {@code null} element, and throws {@code IllegalArgumentException} if it does. * * @param a the array to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @throws IllegalArgumentException if a {@code null} element is found in the array */ public static void checkElementNotNull(final Object[] a, final String argNameOrErrorMsg) throws IllegalArgumentException { if (isEmpty(a)) { return; } for (final Object e : a) { if (e == null) { if (isArgNameOnly(argNameOrErrorMsg)) { throw new IllegalArgumentException("null element is found in " + argNameOrErrorMsg); } else { throw new IllegalArgumentException(argNameOrErrorMsg); } } } } /** * Check if the specified {@code Collection} not contains any {@code null} element, and throws {@code IllegalArgumentException} if it does. * * @param c the collection to check * @throws IllegalArgumentException if {@code null} element found in {@code c} */ public static void checkElementNotNull(final Collection c) throws IllegalArgumentException { if (isEmpty(c)) { return; } for (final Object e : c) { if (e == null) { throw new IllegalArgumentException("null element is found in collection"); } } } /** * Check if the specified {@code Collection} not contains any {@code null} element, and throws {@code IllegalArgumentException} if it does. * * @param c the collection to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @throws IllegalArgumentException if {@code null} element found in {@code c} */ public static void checkElementNotNull(final Collection c, final String argNameOrErrorMsg) throws IllegalArgumentException { if (isEmpty(c)) { return; } for (final Object e : c) { if (e == null) { if (isArgNameOnly(argNameOrErrorMsg)) { throw new IllegalArgumentException("null element is found in " + argNameOrErrorMsg); } else { throw new IllegalArgumentException(argNameOrErrorMsg); } } } } /** * Check if the specified {@code Map} not contains any {@code null} key, and throws {@code IllegalArgumentException} if it does. * * @param m the map to check * @throws IllegalArgumentException if {@code null} key found in {@code m} */ public static void checkKeyNotNull(final Map m) throws IllegalArgumentException { if (isEmpty(m)) { return; } for (final Object e : m.keySet()) { if (e == null) { throw new IllegalArgumentException("null key is found in Map"); } } } /** * Check if the specified {@code Map} not contains any {@code null} key, and throws {@code IllegalArgumentException} if it does. * * @param m the map to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @throws IllegalArgumentException if {@code null} key found in {@code m} */ public static void checkKeyNotNull(final Map m, final String argNameOrErrorMsg) throws IllegalArgumentException { if (isEmpty(m)) { return; } for (final Object e : m.keySet()) { if (e == null) { if (isArgNameOnly(argNameOrErrorMsg)) { throw new IllegalArgumentException("null key is found in " + argNameOrErrorMsg); } else { throw new IllegalArgumentException(argNameOrErrorMsg); } } } } /** * Check if the specified {@code Map} not contains any {@code null} value, and throws {@code IllegalArgumentException} if it does. * * @param m the map to check * @throws IllegalArgumentException if {@code null} value found in {@code m} */ public static void checkValueNotNull(final Map m) throws IllegalArgumentException { if (isEmpty(m)) { return; } for (final Object e : m.values()) { if (e == null) { throw new IllegalArgumentException("null value is found in Map"); } } } /** * Check if the specified {@code Map} not contains any {@code null} value, and throws {@code IllegalArgumentException} if it does. * * @param m the map to check * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @throws IllegalArgumentException if {@code null} value found in {@code m} */ public static void checkValueNotNull(final Map m, final String argNameOrErrorMsg) throws IllegalArgumentException { if (isEmpty(m)) { return; } for (final Object e : m.values()) { if (e == null) { if (isArgNameOnly(argNameOrErrorMsg)) { throw new IllegalArgumentException("null value is found in " + argNameOrErrorMsg); } else { throw new IllegalArgumentException(argNameOrErrorMsg); } } } } /** * * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param argNameOrErrorMsg the name of the argument or an error message to be used in the exception * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final Object argNameOrErrorMsg) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(String.valueOf(argNameOrErrorMsg)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param errorMessageArgs the arguments to be substituted into the message template. Arguments are converted to strings using {@link String#valueOf(Object)}. * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final Object... errorMessageArgs) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, errorMessageArgs)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p the parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final char p) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p the parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final int p) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p the parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final long p) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p the parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final double p) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p the parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final Object p) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final char p1, final char p2) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final char p1, final int p2) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final char p1, final long p2) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final char p1, final double p2) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final char p1, final Object p2) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final int p1, final char p2) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final int p1, final int p2) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final int p1, final long p2) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final int p1, final double p2) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final int p1, final Object p2) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final long p1, final char p2) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final long p1, final int p2) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final long p1, final long p2) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final long p1, final double p2) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final long p1, final Object p2) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final double p1, final char p2) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final double p1, final int p2) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final double p1, final long p2) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final double p1, final double p2) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final double p1, final Object p2) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final Object p1, final char p2) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final Object p1, final int p2) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final Object p1, final long p2) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final Object p1, final double p2) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final Object p1, final Object p2) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @param p3 the third parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final Object p1, final Object p2, final Object p3) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2, p3)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @param p3 the third parameter to be used in the exception message * @param p4 the third parameter to be used in the exception message * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final String errorMessageTemplate, final Object p1, final Object p2, final Object p3, final Object p4) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2, p3, p4)); } } /** * Check if the specified {@code expression} involving one or more parameters of the calling method is {@code true}, and throws {@code IllegalArgumentException} if it is not. * * @param b a boolean expression * @param errorMessageSupplier a supplier of the exception message to use if the check fails; will not be invoked if the check passes * @throws IllegalArgumentException if {@code expression} is false */ public static void checkArgument(final boolean b, final Supplier errorMessageSupplier) throws IllegalArgumentException { if (!b) { throw new IllegalArgumentException(errorMessageSupplier.get()); } } /** * * @param template * @param arg * @return */ static String format(String template, final Object arg) { template = String.valueOf(template); // null -> "null" // start substituting the arguments into the '%s' placeholders final StringBuilder sb = Objectory.createStringBuilder(template.length() + 16); String placeholder = "{}"; int placeholderStart = template.indexOf(placeholder); if (placeholderStart < 0) { placeholder = "%s"; placeholderStart = template.indexOf(placeholder); } if (placeholderStart >= 0) { sb.append(template, 0, placeholderStart); sb.append(toString(arg)); sb.append(template, placeholderStart + 2, template.length()); } else { sb.append(" ["); sb.append(toString(arg)); sb.append(']'); } final String result = sb.toString(); Objectory.recycle(sb); return result; } /** * * @param template * @param arg1 * @param arg2 * @return */ static String format(String template, final Object arg1, final Object arg2) { template = String.valueOf(template); // null -> "null" // start substituting the arguments into the '%s' placeholders final StringBuilder sb = Objectory.createStringBuilder(template.length() + 32); String placeholder = "{}"; int placeholderStart = template.indexOf(placeholder); if (placeholderStart < 0) { placeholder = "%s"; placeholderStart = template.indexOf(placeholder); } int templateStart = 0; int cnt = 0; if (placeholderStart >= 0) { cnt++; sb.append(template, templateStart, placeholderStart); sb.append(toString(arg1)); templateStart = placeholderStart + 2; placeholderStart = template.indexOf(placeholder, templateStart); if (placeholderStart >= 0) { cnt++; sb.append(template, templateStart, placeholderStart); sb.append(toString(arg2)); templateStart = placeholderStart + 2; } sb.append(template, templateStart, template.length()); } if (cnt == 0) { sb.append(" ["); sb.append(toString(arg1)); sb.append(", "); sb.append(toString(arg2)); sb.append(']'); } else if (cnt == 1) { sb.append(" ["); sb.append(toString(arg2)); sb.append(']'); } final String result = sb.toString(); Objectory.recycle(sb); return result; } /** * * @param template * @param arg1 * @param arg2 * @param arg3 * @return */ static String format(String template, final Object arg1, final Object arg2, final Object arg3) { template = String.valueOf(template); // null -> "null" // start substituting the arguments into the '%s' placeholders final StringBuilder sb = Objectory.createStringBuilder(template.length() + 48); String placeholder = "{}"; int placeholderStart = template.indexOf(placeholder); if (placeholderStart < 0) { placeholder = "%s"; placeholderStart = template.indexOf(placeholder); } int templateStart = 0; int cnt = 0; if (placeholderStart >= 0) { cnt++; sb.append(template, templateStart, placeholderStart); sb.append(toString(arg1)); templateStart = placeholderStart + 2; placeholderStart = template.indexOf(placeholder, templateStart); if (placeholderStart >= 0) { cnt++; sb.append(template, templateStart, placeholderStart); sb.append(toString(arg2)); templateStart = placeholderStart + 2; placeholderStart = template.indexOf(placeholder, templateStart); if (placeholderStart >= 0) { cnt++; sb.append(template, templateStart, placeholderStart); sb.append(toString(arg3)); templateStart = placeholderStart + 2; } } sb.append(template, templateStart, template.length()); } if (cnt == 0) { sb.append(" ["); sb.append(toString(arg1)); sb.append(", "); sb.append(toString(arg2)); sb.append(", "); sb.append(toString(arg3)); sb.append(']'); } else if (cnt == 1) { sb.append(" ["); sb.append(toString(arg2)); sb.append(", "); sb.append(toString(arg3)); sb.append(']'); } else if (cnt == 2) { sb.append(" ["); sb.append(toString(arg3)); sb.append(']'); } final String result = sb.toString(); Objectory.recycle(sb); return result; } /** * Substitutes each {@code %s} in {@code template} with an argument. These are matched by * position: the first {@code %s} gets {@code args[0]}, etc. If there are more arguments than * placeholders, the unmatched arguments will be appended to the end of the formatted message in * square braces. * * @param template a {@code non-null} string containing 0 or more {@code %s} placeholders. * @param args the arguments to be substituted into the message template. Arguments are converted * to strings using {@link String#valueOf(Object)}. Arguments can be {@code null}. * @return */ // Note that this is somewhat-improperly used from Verify.java as well. static String format(String template, final Object... args) { template = String.valueOf(template); // null -> "null" if (isEmpty(args)) { return template; } // start substituting the arguments into the '%s' placeholders final StringBuilder sb = Objectory.createStringBuilder(template.length() + 16 * args.length); int templateStart = 0; int i = 0; String placeholder = "{}"; int placeholderStart = template.indexOf(placeholder); if (placeholderStart < 0) { placeholder = "%s"; placeholderStart = template.indexOf(placeholder); } while (placeholderStart >= 0 && i < args.length) { sb.append(template, templateStart, placeholderStart); sb.append(toString(args[i++])); templateStart = placeholderStart + 2; placeholderStart = template.indexOf(placeholder, templateStart); } sb.append(template, templateStart, template.length()); // if we run out of placeholders, append the extra args in square braces if (i < args.length) { sb.append(" ["); sb.append(toString(args[i++])); while (i < args.length) { sb.append(", "); sb.append(toString(args[i++])); } sb.append(']'); } final String result = sb.toString(); Objectory.recycle(sb); return result; } /** * * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b) throws IllegalStateException { if (!b) { throw new IllegalStateException(); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessage the name of the argument or an error message to be used in the exception * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final Object errorMessage) throws IllegalStateException { if (!b) { throw new IllegalStateException(String.valueOf(errorMessage)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param errorMessageArgs the arguments to be substituted into the message template. Arguments are converted to strings using {@link String#valueOf(Object)}. * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final Object... errorMessageArgs) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, errorMessageArgs)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p the parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final char p) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p the parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final int p) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p the parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final long p) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p the parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final double p) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p the parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final Object p) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final char p1, final char p2) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final char p1, final int p2) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final char p1, final long p2) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final char p1, final double p2) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final char p1, final Object p2) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final int p1, final char p2) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final int p1, final int p2) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final int p1, final long p2) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final int p1, final double p2) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final int p1, final Object p2) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final long p1, final char p2) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final long p1, final int p2) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final long p1, final long p2) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final long p1, final double p2) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final long p1, final Object p2) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final double p1, final char p2) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final double p1, final int p2) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final double p1, final long p2) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final double p1, final double p2) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final double p1, final Object p2) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final Object p1, final char p2) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final Object p1, final int p2) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final Object p1, final long p2) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final Object p1, final double p2) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final Object p1, final Object p2) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @param p3 the third parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final Object p1, final Object p2, final Object p3) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2, p3)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageTemplate a template for the exception message should the check fail. The message is formed by replacing each {} or %s placeholder in the template with an argument. * @param p1 the parameter to be used in the exception message * @param p2 the second parameter to be used in the exception message * @param p3 the third parameter to be used in the exception message * @param p4 the third parameter to be used in the exception message * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final String errorMessageTemplate, final Object p1, final Object p2, final Object p3, final Object p4) throws IllegalStateException { if (!b) { throw new IllegalStateException(format(errorMessageTemplate, p1, p2, p3, p4)); } } /** * Check if the specified {@code expression} involving the state check of the calling instance is {@code true}, and throws {@code IllegalStateException} if it is not. * * @param b a boolean expression * @param errorMessageSupplier a supplier of the exception message to use if the check fails; will not be invoked if the check passes * @throws IllegalStateException if {@code expression} is false */ public static void checkState(final boolean b, final Supplier errorMessageSupplier) throws IllegalStateException { if (!b) { throw new IllegalStateException(errorMessageSupplier.get()); } } /** * Checks if the specified object reference is not {@code null}, and throws {@code NullPointerException} if it is. * * @param the type of the object * @param obj the object reference to check for nullity * @return the {@code non-null} object reference that was validated * @throws NullPointerException if the specified {@code obj} is {@code null} * @see Objects#requireNonNull(Object) * @see Objects#requireNonNull(Object, Supplier) * @see Objects#requireNonNullElse(Object, Object) * @see Objects#requireNonNullElseGet(Object, Supplier) */ @Beta public static T requireNonNull(final T obj) throws NullPointerException { if (obj == null) { throw new NullPointerException(); } return obj; } /** * Checks if the specified object reference is not {@code null}, and throws {@code NullPointerException} if it is. * * @param the type of the object * @param obj the object reference to check for nullity * @param errorMessage the detail message to be used in the event that a {@code NullPointerException} is thrown * @return the {@code non-null} object reference that was validated * @throws NullPointerException if the specified {@code obj} is {@code null} * @see Objects#requireNonNull(Object, String) * @see Objects#requireNonNull(Object, Supplier) * @see Objects#requireNonNullElse(Object, Object) * @see Objects#requireNonNullElseGet(Object, Supplier) */ @Beta public static T requireNonNull(final T obj, final String errorMessage) throws NullPointerException { if (obj == null) { if (isArgNameOnly(errorMessage)) { throw new NullPointerException("'" + errorMessage + "' cannot be null"); } else { throw new NullPointerException(errorMessage); } } return obj; } /** * Checks if the specified object reference is not {@code null}, and throws {@code NullPointerException} if it is. * * @param the type of the object * @param obj the object reference to check for nullity * @param errorMessageSupplier the supplier of the detail message to be used in the event that a {@code NullPointerException} is thrown * @return the {@code non-null} object reference that was validated * @throws NullPointerException if the specified {@code obj} is {@code null} * @see Objects#requireNonNull(Object, String) * @see Objects#requireNonNull(Object, Supplier) * @see Objects#requireNonNullElse(Object, Object) * @see Objects#requireNonNullElseGet(Object, Supplier) */ @Beta public static T requireNonNull(final T obj, final Supplier errorMessageSupplier) throws NullPointerException { if (obj == null) { final String errorMessage = errorMessageSupplier.get(); if (isArgNameOnly(errorMessage)) { throw new NullPointerException("'" + errorMessage + "' cannot be null"); } else { throw new NullPointerException(errorMessage); } } return obj; } /** * Compares two boolean values. * * @param a the first boolean value * @param b the second boolean value * @return 0 if both values are equal, 1 if the first value is {@code true} and the second is {@code false}, -1 if the first value is {@code false} and the second is true */ public static int compare(final boolean a, final boolean b) { return (a == b) ? 0 : (a ? 1 : -1); } /** * Compares two char values. * * @param a the first char value * @param b the second char value * @return 0 if both values are equal, 1 if the first value is greater than the second, -1 if the first value is less than the second */ public static int compare(final char a, final char b) { return Character.compare(a, b); } /** * Compares two byte values. * * @param a the first byte value * @param b the second byte value * @return 0 if both values are equal, 1 if the first value is greater than the second, -1 if the first value is less than the second */ public static int compare(final byte a, final byte b) { return Byte.compare(a, b); } /** * Compares two unsigned byte values. * * @param a the first byte value * @param b the second byte value * @return 0 if both values are equal, 1 if the first value is greater than the second, -1 if the first value is less than the second * @see Byte#compareUnsigned(byte, byte) */ public static int compareUnsigned(final byte a, final byte b) { return Byte.compareUnsigned(a, b); } /** * Compares two short values. * * @param a the first short value * @param b the second short value * @return 0 if both values are equal, 1 if the first value is greater than the second, -1 if the first value is less than the second */ public static int compare(final short a, final short b) { return Short.compare(a, b); } /** * Compares two unsigned short values. * * @param a the first short value * @param b the second short value * @return 0 if both values are equal, 1 if the first value is greater than the second, -1 if the first value is less than the second * @see Short#compareUnsigned(short, short) */ public static int compareUnsigned(final short a, final short b) { return Short.compareUnsigned(a, b); } /** * Compares two int values. * * @param a the first int value * @param b the second int value * @return 0 if both values are equal, 1 if the first value is greater than the second, -1 if the first value is less than the second */ public static int compare(final int a, final int b) { return Integer.compare(a, b); } /** * Compares two unsigned int values. * * @param a the first int value * @param b the second int value * @return 0 if both values are equal, 1 if the first value is greater than the second, -1 if the first value is less than the second * @see Integer#compareUnsigned(int, int) */ public static int compareUnsigned(final int a, final int b) { return Integer.compareUnsigned(a, b); } /** * Compares two long values. * * @param a the first long value * @param b the second long value * @return 0 if both values are equal, 1 if the first value is greater than the second, -1 if the first value is less than the second */ public static int compare(final long a, final long b) { return Long.compare(a, b); } /** * Compares two unsigned long values. * * @param a the first long value * @param b the second long value * @return 0 if both values are equal, 1 if the first value is greater than the second, -1 if the first value is less than the second * @see Long#compareUnsigned(long, long) */ public static int compareUnsigned(final long a, final long b) { return Long.compareUnsigned(a, b); } /** * Compares two float values. * * @param a the first float value * @param b the second float value * @return 0 if both values are equal, 1 if the first value is greater than the second, -1 if the first value is less than the second */ public static int compare(final float a, final float b) { return Float.compare(a, b); } /** * Compares two double values. * * @param a the first double value * @param b the second double value * @return 0 if both values are equal, 1 if the first value is greater than the second, -1 if the first value is less than the second */ public static int compare(final double a, final double b) { return Double.compare(a, b); } /** * Compares two {@code Comparable} object values. ({@code null} is considered as the smallest value in nature order). * * @param a the first object value * @param b the second object value * @return 0 if both values are equal, 1 if the first value is greater than the second, -1 if the first value is less than the second */ public static > int compare(final T a, final T b) { return a == null ? (b == null ? 0 : -1) : (b == null ? 1 : a.compareTo(b)); } /** * Compares two {@code Comparable} object values using the specified {@code Comparator}. * * @param * @param a the first object value * @param b the second object value * @param cmp the comparator to be used * @return 0 if both values are equal, 1 if the first value is greater than the second, -1 if the first value is less than the second */ public static int compare(final T a, final T b, final Comparator cmp) { if (cmp == null) { return NATURAL_COMPARATOR.compare(a, b); } return cmp.compare(a, b); } /** * Compares two pairs of values (a1, b1) and (a2, b2) until they are not equal. ({@code null} is considered as the smallest value in nature order). * Returns 0 if all pairs of values are equal. * * @param the type of the first pair of values, which must be comparable * @param the type of the second pair of values, which must be comparable * @param a1 the first value of the first pair * @param b1 the second value of the first pair * @param a2 the first value of the second pair * @param b2 the second value of the second pair * @return a negative integer, zero, or a positive integer as the first value is less than, equal to, or greater than the second values in the specified pairs. */ public static , T2 extends Comparable> int compare(final T1 a1, final T1 b1, final T2 a2, final T2 b2) { final int ret = compare(a1, b1); return ret == 0 ? compare(a2, b2) : ret; } /** * Compares three pairs of values (a1, b1), (a2, b2), and (a3, b3) until they are not equal. ({@code null} is considered as the smallest value in nature order). * Returns 0 if all pairs of values are equal. * * @param the type of the first pair of values, which must be comparable * @param the type of the second pair of values, which must be comparable * @param the type of the third pair of values, which must be comparable * @param a1 the first value of the first pair * @param b1 the second value of the first pair * @param a2 the first value of the second pair * @param b2 the second value of the second pair * @param a3 the first value of the third pair * @param b3 the second value of the third pair * @return a negative integer, zero, or a positive integer as the first value is less than, equal to, or greater than the second values in the specified pairs. */ @SuppressWarnings("java:S1871") public static , T2 extends Comparable, T3 extends Comparable> int compare(final T1 a1, final T1 b1, final T2 a2, final T2 b2, final T3 a3, final T3 b3) { int ret = 0; if (((ret = compare(a1, b1)) != 0) || ((ret = compare(a2, b2)) != 0)) { return ret; } return compare(a3, b3); } /** * Compares four pairs of values (a1, b1), (a2, b2), (a3, b3), and (a4, b4) until they are not equal. ({@code null} is considered as the smallest value in nature order). * Returns 0 if all pairs of values are equal. * * @param the type of the first pair of values, which must be comparable * @param the type of the second pair of values, which must be comparable * @param the type of the third pair of values, which must be comparable * @param the type of the fourth pair of values, which must be comparable * @param a1 the first value of the first pair * @param b1 the second value of the first pair * @param a2 the first value of the second pair * @param b2 the second value of the second pair * @param a3 the first value of the third pair * @param b3 the second value of the third pair * @param a4 the first value of the fourth pair * @param b4 the second value of the fourth pair * @return a negative integer, zero, or a positive integer as the first value is less than, equal to, or greater than the second values in the specified pairs. * @deprecated replaced by {@link Builder#compare(Comparable, Comparable)} * @see Builder#compare(Comparable, Comparable) */ @Deprecated @SuppressWarnings("java:S1871") public static , T2 extends Comparable, T3 extends Comparable, T4 extends Comparable> int compare(final T1 a1, final T1 b1, final T2 a2, final T2 b2, final T3 a3, final T3 b3, final T4 a4, final T4 b4) { int ret = 0; if (((ret = compare(a1, b1)) != 0) || ((ret = compare(a2, b2)) != 0) || ((ret = compare(a3, b3)) != 0)) { return ret; } return compare(a4, b4); } /** * Compares five pairs of values (a1, b1), (a2, b2), (a3, b3), (a4, b4), and (a5, b5) until they are not equal. ({@code null} is considered as the smallest value in nature order). * Returns 0 if all pairs of values are equal. * * @param the type of the first pair of values, which must be comparable * @param the type of the second pair of values, which must be comparable * @param the type of the third pair of values, which must be comparable * @param the type of the fourth pair of values, which must be comparable * @param the type of the fifth pair of values, which must be comparable * @param a1 the first value of the first pair * @param b1 the second value of the first pair * @param a2 the first value of the second pair * @param b2 the second value of the second pair * @param a3 the first value of the third pair * @param b3 the second value of the third pair * @param a4 the first value of the fourth pair * @param b4 the second value of the fourth pair * @param a5 the first value of the fifth pair * @param b5 the second value of the fifth pair * @return a negative integer, zero, or a positive integer as the first value is less than, equal to, or greater than the second values in the specified pairs. * @deprecated replaced by {@link Builder#compare(Comparable, Comparable)} * @see Builder#compare(Comparable, Comparable) */ @Deprecated @SuppressWarnings("java:S1871") public static , T2 extends Comparable, T3 extends Comparable, T4 extends Comparable, T5 extends Comparable> int compare( final T1 a1, final T1 b1, final T2 a2, final T2 b2, final T3 a3, final T3 b3, final T4 a4, final T4 b4, final T5 a5, final T5 b5) { int ret = 0; if (((ret = compare(a1, b1)) != 0) || ((ret = compare(a2, b2)) != 0) || ((ret = compare(a3, b3)) != 0) || ((ret = compare(a4, b4)) != 0)) { return ret; } return compare(a5, b5); } /** * Compares six pairs of values (a1, b1), (a2, b2), (a3, b3), (a4, b4), (a5, b5), and (a6, b6) until they are not equal. ({@code null} is considered as the smallest value in nature order). * Returns 0 if all pairs of values are equal. * * @param the type of the first pair of values, which must be comparable * @param the type of the second pair of values, which must be comparable * @param the type of the third pair of values, which must be comparable * @param the type of the fourth pair of values, which must be comparable * @param the type of the fifth pair of values, which must be comparable * @param the type of the sixth pair of values, which must be comparable * @param a1 the first value of the first pair * @param b1 the second value of the first pair * @param a2 the first value of the second pair * @param b2 the second value of the second pair * @param a3 the first value of the third pair * @param b3 the second value of the third pair * @param a4 the first value of the fourth pair * @param b4 the second value of the fourth pair * @param a5 the first value of the fifth pair * @param b5 the second value of the fifth pair * @param a6 the first value of the sixth pair * @param b6 the second value of the sixth pair * @return a negative integer, zero, or a positive integer as the first value is less than, equal to, or greater than the second values in the specified pairs. * @deprecated replaced by {@link Builder#compare(Comparable, Comparable)} * @see Builder#compare(Comparable, Comparable) */ @Deprecated @SuppressWarnings("java:S1871") public static , T2 extends Comparable, T3 extends Comparable, T4 extends Comparable, T5 extends Comparable, T6 extends Comparable> int compare( final T1 a1, final T1 b1, final T2 a2, final T2 b2, final T3 a3, final T3 b3, final T4 a4, final T4 b4, final T5 a5, final T5 b5, final T6 a6, final T6 b6) { int ret = 0; if (((ret = compare(a1, b1)) != 0) || ((ret = compare(a2, b2)) != 0) || ((ret = compare(a3, b3)) != 0) || ((ret = compare(a4, b4)) != 0) || (ret = compare(a5, b5)) != 0) { return ret; } return compare(a6, b6); } /** * Compares seven pairs of values (a1, b1), (a2, b2), (a3, b3), (a4, b4), (a5, b5), (a6, b6), and (a7, b7) until they are not equal. ({@code null} is considered as the smallest value in nature order). * Returns 0 if all pairs of values are equal. * * @param the type of the first pair of values, which must be comparable * @param the type of the second pair of values, which must be comparable * @param the type of the third pair of values, which must be comparable * @param the type of the fourth pair of values, which must be comparable * @param the type of the fifth pair of values, which must be comparable * @param the type of the sixth pair of values, which must be comparable * @param the type of the seventh pair of values, which must be comparable * @param a1 the first value of the first pair * @param b1 the second value of the first pair * @param a2 the first value of the second pair * @param b2 the second value of the second pair * @param a3 the first value of the third pair * @param b3 the second value of the third pair * @param a4 the first value of the fourth pair * @param b4 the second value of the fourth pair * @param a5 the first value of the fifth pair * @param b5 the second value of the fifth pair * @param a6 the first value of the sixth pair * @param b6 the second value of the sixth pair * @param a7 the first value of the seventh pair * @param b7 the second value of the seventh pair * @return a negative integer, zero, or a positive integer as the first value is less than, equal to, or greater than the second values in the specified pairs * @deprecated replaced by {@link Builder#compare(Comparable, Comparable)} * @see Builder#compare(Comparable, Comparable) */ @Deprecated @SuppressWarnings("java:S1871") public static , T2 extends Comparable, T3 extends Comparable, T4 extends Comparable, T5 extends Comparable, T6 extends Comparable, T7 extends Comparable> int compare( final T1 a1, final T1 b1, final T2 a2, final T2 b2, final T3 a3, final T3 b3, final T4 a4, final T4 b4, final T5 a5, final T5 b5, final T6 a6, final T6 b6, final T7 a7, final T7 b7) { int ret = 0; if (((ret = compare(a1, b1)) != 0) || ((ret = compare(a2, b2)) != 0) || ((ret = compare(a3, b3)) != 0) || ((ret = compare(a4, b4)) != 0) || ((ret = compare(a5, b5)) != 0) || ((ret = compare(a6, b6)) != 0)) { return ret; } return compare(a7, b7); } /* * Tested by ArraysTest.test_compare_perf @Test public void test_compare_perf() { final int len = 1000; final int[] a = Array.range(0, len); final int[] b = Array.range(0, len); a[len - 1] = 0; b[len - 1] = 1; assertEquals(-1, compare(a, b)); assertEquals(-1, Arrays.compare(a, b)); Profiler.run(1, 1000, 3, "compare(...)", () -> assertEquals(-1, compare(a, b))).printResult(); Profiler.run(1, 1000, 3, "Arrays.compare(...)", () -> assertEquals(-1, Arrays.compare(a, b))).printResult(); } */ private static final int MISMATCH_THRESHOLD = 1000; /** * Compares two arrays lexicographically. * * @param a the first array to compare * @param b the second array to compare * @return a negative integer, zero, or a positive integer as the first array is less than, equal to, or greater than the second */ public static int compare(final boolean[] a, final boolean[] b) { if (isEmpty(a)) { return isEmpty(b) ? 0 : -1; } else if (isEmpty(b)) { return 1; } final int minLen = N.min(a.length, b.length); if (minLen > MISMATCH_THRESHOLD) { return Arrays.compare(a, b); } for (int i = 0; i < minLen; i++) { if (a[i] != b[i]) { return a[i] ? 1 : -1; } } return Integer.compare(a.length, b.length); } /** * Compares two arrays lexicographically over the specified range. * * @param a the first array to compare * @param fromIndexA the starting index in the first array * @param b the second array to compare * @param fromIndexB the starting index in the second array * @param len the number of elements to compare * @return a negative integer, zero, or a positive integer as the first array is less than, equal to, or greater than the second array * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified ranges are out of bounds */ public static int compare(final boolean[] a, final int fromIndexA, final boolean[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return 0; } if (len > MISMATCH_THRESHOLD) { return Arrays.compare(a, fromIndexA, fromIndexA + len, b, fromIndexB, fromIndexB + len); } for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (a[i] != b[j]) { return a[i] ? 1 : -1; } } return 0; } /** * Compares two arrays lexicographically. * * @param a the first array to compare * @param b the second array to compare * @return a negative integer, zero, or a positive integer as the first array is less than, equal to, or greater than the second */ public static int compare(final char[] a, final char[] b) { if (isEmpty(a)) { return isEmpty(b) ? 0 : -1; } else if (isEmpty(b)) { return 1; } final int minLen = N.min(a.length, b.length); if (minLen > MISMATCH_THRESHOLD) { return Arrays.compare(a, b); } for (int i = 0; i < minLen; i++) { if (a[i] != b[i]) { return a[i] > b[i] ? 1 : -1; } } return Integer.compare(a.length, b.length); } /** * Compares two arrays lexicographically over the specified range. * * @param a the first array to compare * @param fromIndexA the starting index in the first array * @param b the second array to compare * @param fromIndexB the starting index in the second array * @param len the number of elements to compare * @return a negative integer, zero, or a positive integer as the first array is less than, equal to, or greater than the second array * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified ranges are out of bounds */ public static int compare(final char[] a, final int fromIndexA, final char[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return 0; } if (len > MISMATCH_THRESHOLD) { return Arrays.compare(a, fromIndexA, fromIndexA + len, b, fromIndexB, fromIndexB + len); } for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (a[i] != b[j]) { return a[i] > b[i] ? 1 : -1; } } return 0; } /** * Compares two arrays lexicographically. * * @param a the first array to compare * @param b the second array to compare * @return a negative integer, zero, or a positive integer as the first array is less than, equal to, or greater than the second */ public static int compare(final byte[] a, final byte[] b) { if (isEmpty(a)) { return isEmpty(b) ? 0 : -1; } else if (isEmpty(b)) { return 1; } final int minLen = N.min(a.length, b.length); if (minLen > MISMATCH_THRESHOLD) { return Arrays.compare(a, b); } for (int i = 0; i < minLen; i++) { if (a[i] != b[i]) { return a[i] > b[i] ? 1 : -1; } } return Integer.compare(a.length, b.length); } /** * Compares two arrays lexicographically over the specified range. * * @param a the first array to compare * @param fromIndexA the starting index in the first array * @param b the second array to compare * @param fromIndexB the starting index in the second array * @param len the number of elements to compare * @return a negative integer, zero, or a positive integer as the first array is less than, equal to, or greater than the second array * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified ranges are out of bounds */ public static int compare(final byte[] a, final int fromIndexA, final byte[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return 0; } if (len > MISMATCH_THRESHOLD) { return Arrays.compare(a, fromIndexA, fromIndexA + len, b, fromIndexB, fromIndexB + len); } for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (a[i] != b[j]) { return a[i] > b[i] ? 1 : -1; } } return 0; } /** * Compares two arrays lexicographically, treating the values as unsigned. * * @param a the first array to compare * @param b the second array to compare * @return a negative integer, zero, or a positive integer as the first array is less than, equal to, or greater than the second * @see Arrays#compareUnsigned(byte[], byte[]) * @see Byte#compareUnsigned(byte, byte) */ public static int compareUnsigned(final byte[] a, final byte[] b) { if (isEmpty(a)) { return isEmpty(b) ? 0 : -1; } else if (isEmpty(b)) { return 1; } return Arrays.compareUnsigned(a, b); } /** * Compares two subarrays lexicographically, treating the values as unsigned. * * @param a the first array to compare * @param fromIndexA the starting index (inclusive) of the first subarray * @param b the second array to compare * @param fromIndexB the starting index (inclusive) of the second subarray * @param len the length of the subarrays to compare * @return a negative integer, zero, or a positive integer as the first subarray is less than, equal to, or greater than the second subarray * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified indices are out of bounds * @see Arrays#compareUnsigned(byte[], int, int, byte[], int, int) * @see Byte#compareUnsigned(byte, byte) */ public static int compareUnsigned(final byte[] a, final int fromIndexA, final byte[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if (isEmpty(a)) { return isEmpty(b) ? 0 : -1; } else if (isEmpty(b)) { return 1; } return Arrays.compareUnsigned(a, fromIndexA, fromIndexA + len, b, fromIndexB, fromIndexB + len); } /** * Compares two arrays lexicographically. * * @param a the first array to compare * @param b the second array to compare * @return a negative integer, zero, or a positive integer as the first array is less than, equal to, or greater than the second */ public static int compare(final short[] a, final short[] b) { if (isEmpty(a)) { return isEmpty(b) ? 0 : -1; } else if (isEmpty(b)) { return 1; } final int minLen = N.min(a.length, b.length); if (minLen > MISMATCH_THRESHOLD) { return Arrays.compare(a, b); } for (int i = 0; i < minLen; i++) { if (a[i] != b[i]) { return a[i] > b[i] ? 1 : -1; } } return Integer.compare(a.length, b.length); } /** * Compares two arrays lexicographically over the specified range. * * @param a the first array to compare * @param fromIndexA the starting index in the first array * @param b the second array to compare * @param fromIndexB the starting index in the second array * @param len the number of elements to compare * @return a negative integer, zero, or a positive integer as the first array is less than, equal to, or greater than the second array * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified ranges are out of bounds */ public static int compare(final short[] a, final int fromIndexA, final short[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return 0; } if (len > MISMATCH_THRESHOLD) { return Arrays.compare(a, fromIndexA, fromIndexA + len, b, fromIndexB, fromIndexB + len); } for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (a[i] != b[j]) { return a[i] > b[i] ? 1 : -1; } } return 0; } /** * Compares two arrays lexicographically, treating the values as unsigned. * * @param a the first array to compare * @param b the second array to compare * @return a negative integer, zero, or a positive integer as the first array is less than, equal to, or greater than the second * @see Arrays#compareUnsigned(short[], short[]) * @see Short#compareUnsigned(short, short) */ public static int compareUnsigned(final short[] a, final short[] b) { if (isEmpty(a)) { return isEmpty(b) ? 0 : -1; } else if (isEmpty(b)) { return 1; } return Arrays.compareUnsigned(a, b); } /** * Compares two subarrays lexicographically, treating the values as unsigned. * * @param a the first array to compare * @param fromIndexA the starting index (inclusive) of the first subarray * @param b the second array to compare * @param fromIndexB the starting index (inclusive) of the second subarray * @param len the length of the subarrays to compare * @return a negative integer, zero, or a positive integer as the first subarray is less than, equal to, or greater than the second subarray * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified indices are out of bounds * @see Arrays#compareUnsigned(short[], int, int, short[], int, int) * @see Short#compareUnsigned(short, short) */ public static int compareUnsigned(final short[] a, final int fromIndexA, final short[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if (isEmpty(a)) { return isEmpty(b) ? 0 : -1; } else if (isEmpty(b)) { return 1; } return Arrays.compareUnsigned(a, fromIndexA, fromIndexA + len, b, fromIndexB, fromIndexB + len); } /** * Compares two arrays lexicographically. * * @param a the first array to compare * @param b the second array to compare * @return a negative integer, zero, or a positive integer as the first array is less than, equal to, or greater than the second */ public static int compare(final int[] a, final int[] b) { if (isEmpty(a)) { return isEmpty(b) ? 0 : -1; } else if (isEmpty(b)) { return 1; } final int minLen = N.min(a.length, b.length); if (minLen > MISMATCH_THRESHOLD) { return Arrays.compare(a, b); } for (int i = 0; i < minLen; i++) { if (a[i] != b[i]) { return a[i] > b[i] ? 1 : -1; } } return Integer.compare(a.length, b.length); } /** * Compares two arrays lexicographically over the specified range. * * @param a the first array to compare * @param fromIndexA the starting index in the first array * @param b the second array to compare * @param fromIndexB the starting index in the second array * @param len the number of elements to compare * @return a negative integer, zero, or a positive integer as the first array is less than, equal to, or greater than the second array * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified ranges are out of bounds */ public static int compare(final int[] a, final int fromIndexA, final int[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return 0; } if (len > MISMATCH_THRESHOLD) { return Arrays.compare(a, fromIndexA, fromIndexA + len, b, fromIndexB, fromIndexB + len); } for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (a[i] != b[j]) { return a[i] > b[i] ? 1 : -1; } } return 0; } /** * Compares two arrays lexicographically, treating the values as unsigned. * * @param a the first array to compare * @param b the second array to compare * @return a negative integer, zero, or a positive integer as the first array is less than, equal to, or greater than the second * @see Arrays#compareUnsigned(int[], int[]) * @see Integer#compareUnsigned(int, int) */ public static int compareUnsigned(final int[] a, final int[] b) { if (isEmpty(a)) { return isEmpty(b) ? 0 : -1; } else if (isEmpty(b)) { return 1; } return Arrays.compareUnsigned(a, b); } /** * Compares two subarrays lexicographically, treating the values as unsigned. * * @param a the first array to compare * @param fromIndexA the starting index (inclusive) of the first subarray * @param b the second array to compare * @param fromIndexB the starting index (inclusive) of the second subarray * @param len the length of the subarrays to compare * @return a negative integer, zero, or a positive integer as the first subarray is less than, equal to, or greater than the second subarray * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified indices are out of bounds * @see Arrays#compareUnsigned(int[], int, int, int[], int, int) * @see Integer#compareUnsigned(int, int) */ public static int compareUnsigned(final int[] a, final int fromIndexA, final int[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if (isEmpty(a)) { return isEmpty(b) ? 0 : -1; } else if (isEmpty(b)) { return 1; } return Arrays.compareUnsigned(a, fromIndexA, fromIndexA + len, b, fromIndexB, fromIndexB + len); } /** * Compares two arrays lexicographically. * * @param a the first array to compare * @param b the second array to compare * @return a negative integer, zero, or a positive integer as the first array is less than, equal to, or greater than the second */ public static int compare(final long[] a, final long[] b) { if (isEmpty(a)) { return isEmpty(b) ? 0 : -1; } else if (isEmpty(b)) { return 1; } final int minLen = N.min(a.length, b.length); if (minLen > MISMATCH_THRESHOLD) { return Arrays.compare(a, b); } for (int i = 0; i < minLen; i++) { if (a[i] != b[i]) { return a[i] > b[i] ? 1 : -1; } } return Integer.compare(a.length, b.length); } /** * Compares two arrays lexicographically over the specified range. * * @param a the first array to compare * @param fromIndexA the starting index in the first array * @param b the second array to compare * @param fromIndexB the starting index in the second array * @param len the number of elements to compare * @return a negative integer, zero, or a positive integer as the first array is less than, equal to, or greater than the second array * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified ranges are out of bounds */ public static int compare(final long[] a, final int fromIndexA, final long[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return 0; } if (len > MISMATCH_THRESHOLD) { return Arrays.compare(a, fromIndexA, fromIndexA + len, b, fromIndexB, fromIndexB + len); } for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (a[i] != b[j]) { return a[i] > b[i] ? 1 : -1; } } return 0; } /** * Compares two arrays lexicographically, treating the values as unsigned. * * @param a the first array to compare * @param b the second array to compare * @return a negative integer, zero, or a positive integer as the first array is less than, equal to, or greater than the second * @see Arrays#compareUnsigned(long[], long[]) * @see Long#compareUnsigned(long, long) */ public static int compareUnsigned(final long[] a, final long[] b) { if (isEmpty(a)) { return isEmpty(b) ? 0 : -1; } else if (isEmpty(b)) { return 1; } return Arrays.compareUnsigned(a, b); } /** * Compares two subarrays lexicographically, treating the values as unsigned. * * @param a the first array to compare * @param fromIndexA the starting index (inclusive) of the first subarray * @param b the second array to compare * @param fromIndexB the starting index (inclusive) of the second subarray * @param len the length of the subarrays to compare * @return a negative integer, zero, or a positive integer as the first subarray is less than, equal to, or greater than the second subarray * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified indices are out of bounds * @see Arrays#compareUnsigned(long[], int, int, long[], int, int) * @see Long#compareUnsigned(long, long) */ public static int compareUnsigned(final long[] a, final int fromIndexA, final long[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if (isEmpty(a)) { return isEmpty(b) ? 0 : -1; } else if (isEmpty(b)) { return 1; } return Arrays.compareUnsigned(a, fromIndexA, fromIndexA + len, b, fromIndexB, fromIndexB + len); } /** * Compares two arrays lexicographically. * * @param a the first array to compare * @param b the second array to compare * @return a negative integer, zero, or a positive integer as the first array is less than, equal to, or greater than the second */ public static int compare(final float[] a, final float[] b) { if (isEmpty(a)) { return isEmpty(b) ? 0 : -1; } else if (isEmpty(b)) { return 1; } final int minLen = N.min(a.length, b.length); if (minLen > MISMATCH_THRESHOLD) { return Arrays.compare(a, b); } int ret = 0; for (int i = 0; i < minLen; i++) { if ((ret = Float.compare(a[i], b[i])) != 0) { return ret; } } return Integer.compare(a.length, b.length); } /** * Compares two arrays lexicographically over the specified range. * * @param a the first array to compare * @param fromIndexA the starting index in the first array * @param b the second array to compare * @param fromIndexB the starting index in the second array * @param len the number of elements to compare * @return a negative integer, zero, or a positive integer as the first array is less than, equal to, or greater than the second array * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified ranges are out of bounds */ public static int compare(final float[] a, final int fromIndexA, final float[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return 0; } if (len > MISMATCH_THRESHOLD) { return Arrays.compare(a, fromIndexA, fromIndexA + len, b, fromIndexB, fromIndexB + len); } int ret = 0; for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if ((ret = Float.compare(a[i], b[j])) != 0) { return ret; } } return 0; } /** * Compares two arrays lexicographically. * * @param a the first array to compare * @param b the second array to compare * @return a negative integer, zero, or a positive integer as the first array is less than, equal to, or greater than the second */ public static int compare(final double[] a, final double[] b) { if (isEmpty(a)) { return isEmpty(b) ? 0 : -1; } else if (isEmpty(b)) { return 1; } final int minLen = N.min(a.length, b.length); if (minLen > MISMATCH_THRESHOLD) { return Arrays.compare(a, b); } int ret = 0; for (int i = 0; i < minLen; i++) { if ((ret = Double.compare(a[i], b[i])) != 0) { return ret; } } return Integer.compare(a.length, b.length); } /** * Compares two arrays lexicographically over the specified range. * * @param a the first array to compare * @param fromIndexA the starting index in the first array * @param b the second array to compare * @param fromIndexB the starting index in the second array * @param len the number of elements to compare * @return a negative integer, zero, or a positive integer as the first array is less than, equal to, or greater than the second array * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified ranges are out of bounds */ public static int compare(final double[] a, final int fromIndexA, final double[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return 0; } if (len > MISMATCH_THRESHOLD) { return Arrays.compare(a, fromIndexA, fromIndexA + len, b, fromIndexB, fromIndexB + len); } int ret = 0; for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if ((ret = Double.compare(a[i], b[j])) != 0) { return ret; } } return 0; } /** * Compares two arrays lexicographically. ({@code null} is considered as the smallest value in nature order). * * @param a the first array to compare * @param b the second array to compare * @return a negative integer, zero, or a positive integer as the first array is less than, equal to, or greater than the second */ public static > int compare(final T[] a, final T[] b) { final Comparator cmp = NATURAL_COMPARATOR; return compare(a, b, cmp); } /** * Compares two arrays lexicographically over the specified range. ({@code null} is considered as the smallest value in nature order). * * @param a the first array to compare * @param fromIndexA the starting index in the first array * @param b the second array to compare * @param fromIndexB the starting index in the second array * @param len the number of elements to compare * @return a negative integer, zero, or a positive integer as the first array is less than, equal to, or greater than the second array * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified ranges are out of bounds */ public static > int compare(final T[] a, final int fromIndexA, final T[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { return compare(a, fromIndexA, b, fromIndexB, len, NATURAL_COMPARATOR); } /** * Compares two arrays using the specified comparator. * * @param the type of elements in the arrays * @param a the first array to compare * @param b the second array to compare * @param cmp the comparator to compare array elements * @return a negative integer, zero, or a positive integer as the first array is less than, equal to, or greater than the second array */ public static int compare(final T[] a, final T[] b, Comparator cmp) { if (isEmpty(a)) { return isEmpty(b) ? 0 : -1; } else if (isEmpty(b)) { return 1; } cmp = checkComparator(cmp); int ret = 0; for (int i = 0, minLen = N.min(a.length, b.length); i < minLen; i++) { if ((ret = cmp.compare(a[i], b[i])) != 0) { return ret; } } return Integer.compare(a.length, b.length); } /** * Compares two arrays lexicographically over the specified range using the specified comparator. * * @param a the first array to compare * @param fromIndexA the starting index in the first array * @param b the second array to compare * @param fromIndexB the starting index in the second array * @param len the number of elements to compare * @param cmp the comparator to compare array elements * @return a negative integer, zero, or a positive integer as the first array is less than, equal to, or greater than the second array * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified ranges are out of bounds */ public static int compare(final T[] a, final int fromIndexA, final T[] b, final int fromIndexB, final int len, Comparator cmp) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return 0; } cmp = checkComparator(cmp); int ret = 0; for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if ((ret = cmp.compare(a[i], b[j])) != 0) { return ret; } } return 0; } /** * Compares two collections lexicographically over the specified range. ({@code null} is considered as the smallest value in nature order). * * @param a the first collection to compare * @param fromIndexA the starting index in the first collection * @param b the second collection to compare * @param fromIndexB the starting index in the second collection * @param len the number of elements to compare * @return a negative integer, zero, or a positive integer as the first collection is less than, equal to, or greater than the second collection * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified ranges are out of bounds */ public static int compare(final Collection a, final int fromIndexA, final Collection b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { return compare(a, fromIndexA, b, fromIndexB, len, NATURAL_COMPARATOR); } /** * Compares two iterables lexicographically. ({@code null} is considered as the smallest value in nature order). * * @param the type of elements in the iterables, which must be comparable * @param a the first iterable to compare * @param b the second iterable to compare * @return a negative integer, zero, or a positive integer as the first iterable is less than, equal to, or greater than the second iterable */ public static > int compare(final Iterable a, final Iterable b) { final Comparator cmp = NATURAL_COMPARATOR; return compare(a, b, cmp); } /** * Compares two iterators lexicographically. ({@code null} is considered as the smallest value in nature order). * * @param the type of elements in the iterators, which must be comparable * @param a the first iterator to compare * @param b the second iterator to compare * @return a negative integer, zero, or a positive integer as the first iterator is less than, equal to, or greater than the second iterator */ public static > int compare(final Iterator a, final Iterator b) { final Comparator cmp = NATURAL_COMPARATOR; return compare(a, b, cmp); } /** * Compares two collections lexicographically over the specified range using the specified comparator. * * @param the type of elements in the collections * @param a the first collection to compare * @param fromIndexA the starting index in the first collection * @param b the second collection to compare * @param fromIndexB the starting index in the second collection * @param len the number of elements to compare * @param cmp the comparator to compare collection elements * @return a negative integer, zero, or a positive integer as the first collection is less than, equal to, or greater than the second collection * @throws IllegalArgumentException if the specified length is negative * @throws IndexOutOfBoundsException if the specified indices are out of range */ public static int compare(final Collection a, int fromIndexA, final Collection b, int fromIndexB, final int len, Comparator cmp) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, size(a)); checkFromIndexSize(fromIndexB, len, size(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return 0; } cmp = checkComparator(cmp); final Iterator iterA = a.iterator(); final Iterator iterB = b.iterator(); while (fromIndexA-- > 0) { iterA.next(); } while (fromIndexB-- > 0) { iterB.next(); } int ret = 0; for (int i = 0; i < len; i++) { if ((ret = cmp.compare(iterA.next(), iterB.next())) != 0) { return ret; } } return 0; } /** * Compares two iterables using the specified comparator. * * @param the type of elements in the iterables * @param a the first iterable to compare * @param b the second iterable to compare * @param cmp the comparator to compare elements from iterables * @return a negative integer, zero, or a positive integer as the first iterable is less than, equal to, or greater than the second iterable */ public static int compare(final Iterable a, final Iterable b, Comparator cmp) { if (isEmpty(a)) { return isEmpty(b) ? 0 : -1; } else if (isEmpty(b)) { return 1; } cmp = checkComparator(cmp); return compare(a.iterator(), b.iterator(), cmp); } /** * Compares two iterators using the specified comparator. * * @param the type of elements in the iterators * @param a the first iterator to compare * @param b the second iterator to compare * @param cmp the comparator to compare elements from iterators * @return a negative integer, zero, or a positive integer as the first iterator is less than, equal to, or greater than the second iterator */ public static int compare(final Iterator a, final Iterator b, Comparator cmp) { cmp = checkComparator(cmp); final Iterator iterA = a == null ? ObjIterator.empty() : a; final Iterator iterB = b == null ? ObjIterator.empty() : b; int ret = 0; while (iterA.hasNext() && iterB.hasNext()) { if ((ret = cmp.compare(iterA.next(), iterB.next())) != 0) { return ret; } } return iterA.hasNext() ? 1 : (iterB.hasNext() ? -1 : 0); } /** * Compares two strings lexicographically, ignoring case differences. * * @param a the first string to compare * @param b the second string to compare * @return a negative integer, zero, or a positive integer as the first string is less than, equal to, or greater than the second string, ignoring case considerations */ public static int compareIgnoreCase(final String a, final String b) { return a == null ? (b == null ? 0 : -1) : (b == null ? 1 : a.compareToIgnoreCase(b)); } /** * Compares two arrays of strings lexicographically, ignoring case differences. * * @param a the first array of strings to compare * @param b the second array of strings to compare * @return a negative integer, zero, or a positive integer as the first array is less than, equal to, or greater than the second array, ignoring case considerations */ public static int compareIgnoreCase(final String[] a, final String[] b) { return compare(a, b, Comparators.comparingIgnoreCase()); } /** * Compares two beans based on the specified properties. * * @param bean1 the first bean to compare, must not be null * @param bean2 the second bean to compare, must not be null * @param propNamesToCompare the collection of property names to compare, which may be null * @return a negative integer, zero, or a positive integer as the first bean is less than, equal to, or greater than the second bean * @throws IllegalArgumentException if any of the arguments are null * @deprecated call {@code getPropValue} by reflection APIs during comparing or sorting may have a huge impact on performance. Use {@link ComparisonBuilder} instead. * @see Builder#compare(Object, Object, Comparator) * @see ComparisonBuilder */ @Deprecated @SuppressWarnings("rawtypes") public static int compareByProps(@NotNull final Object bean1, @NotNull final Object bean2, final Collection propNamesToCompare) { checkArgNotNull(bean1); checkArgNotNull(bean2); checkArgument(ClassUtil.isBeanClass(bean1.getClass()), "{} is not a bean class", bean1.getClass()); checkArgument(ClassUtil.isBeanClass(bean2.getClass()), "{} is not a bean class", bean2.getClass()); if (isEmpty(propNamesToCompare)) { return 0; } final BeanInfo beanInfo1 = ParserUtil.getBeanInfo(bean1.getClass()); final BeanInfo beanInfo2 = ParserUtil.getBeanInfo(bean2.getClass()); PropInfo propInfo1 = null; PropInfo propInfo2 = null; int ret = 0; for (final String propName : propNamesToCompare) { propInfo1 = beanInfo1.getPropInfo(propName); if (propInfo1 != null) { propInfo2 = beanInfo2.getPropInfo(propInfo1); if (propInfo2 == null) { throw new IllegalArgumentException("No field found in class: " + bean2.getClass() + " by name: " + propName); } } else { propInfo2 = beanInfo2.getPropInfo(propName); if (propInfo2 != null) { propInfo1 = beanInfo1.getPropInfo(propInfo2); } if (propInfo1 == null) { throw new IllegalArgumentException("No field found in class: " + bean1.getClass() + " by name: " + propName); } } if ((ret = compare(propInfo1.getPropValue(bean1), (Comparable) propInfo2.getPropValue(bean2))) != 0) { return ret; } } return 0; } /** * Finds and returns the index of the first mismatch between two arrays. * If the arrays are identical or both are {@code null} or empty, returns -1. * * @param a the first boolean array * @param b the second boolean array * @return the index of the first mismatch, or -1 if the arrays are identical or both are {@code null} or empty. * @see Arrays#mismatch(boolean[], boolean[]) */ public static int mismatch(final boolean[] a, final boolean[] b) { if (a == b) { return -1; } if (isEmpty(a)) { return isEmpty(b) ? -1 : 0; } else if (isEmpty(b)) { return 0; } final int minLen = N.min(a.length, b.length); if (minLen > MISMATCH_THRESHOLD) { return Arrays.mismatch(a, b); } for (int i = 0; i < minLen; i++) { if (a[i] != b[i]) { return i; } } return a.length == b.length ? -1 : minLen; } /** * Finds and returns the index of the first mismatch between two boolean arrays starting from specified indices. * If the arrays are identical in the specified range, returns -1. * * @param a the first boolean array * @param fromIndexA the starting index in the first array * @param b the second boolean array * @param fromIndexB the starting index in the second array * @param len the number of elements to compare * @return the index of the first mismatch, or -1 if the arrays are identical in the specified range * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the starting indices or length are out of bounds * @see Arrays#mismatch(boolean[], int, int, boolean[], int, int) */ public static int mismatch(final boolean[] a, final int fromIndexA, final boolean[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return -1; } if (len > MISMATCH_THRESHOLD) { return Arrays.mismatch(a, fromIndexA, fromIndexA + len, b, fromIndexB, fromIndexB + len); } for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (a[i] != b[j]) { return i - fromIndexA; } } return -1; } /** * Finds and returns the index of the first mismatch between two arrays. * If the arrays are identical or both are {@code null} or empty, returns -1. * * @param a the first char array * @param b the second char array * @return the index of the first mismatch, or -1 if the arrays are identical or both are {@code null} or empty. * @see Arrays#mismatch(char[], char[]) */ public static int mismatch(final char[] a, final char[] b) { if (a == b) { return -1; } if (isEmpty(a)) { return isEmpty(b) ? -1 : 0; } else if (isEmpty(b)) { return 0; } final int minLen = N.min(a.length, b.length); if (minLen > MISMATCH_THRESHOLD) { return Arrays.mismatch(a, b); } for (int i = 0; i < minLen; i++) { if (a[i] != b[i]) { return i; } } return a.length == b.length ? -1 : minLen; } /** * Finds and returns the index of the first mismatch between two char arrays starting from specified indices. * If the arrays are identical in the specified range, returns -1. * * @param a the first char array * @param fromIndexA the starting index in the first array * @param b the second char array * @param fromIndexB the starting index in the second array * @param len the number of elements to compare * @return the index of the first mismatch, or -1 if the arrays are identical in the specified range * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the starting indices or length are out of bounds * @see Arrays#mismatch(char[], int, int, char[], int, int) */ public static int mismatch(final char[] a, final int fromIndexA, final char[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return -1; } if (len > MISMATCH_THRESHOLD) { return Arrays.mismatch(a, fromIndexA, fromIndexA + len, b, fromIndexB, fromIndexB + len); } for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (a[i] != b[j]) { return i - fromIndexA; } } return -1; } /** * Finds and returns the index of the first mismatch between two arrays. * If the arrays are identical or both are {@code null} or empty, returns -1. * * @param a the first byte array * @param b the second byte array * @return the index of the first mismatch, or -1 if the arrays are identical or both are {@code null} or empty. * @see Arrays#mismatch(byte[], byte[]) */ public static int mismatch(final byte[] a, final byte[] b) { if (a == b) { return -1; } if (isEmpty(a)) { return isEmpty(b) ? -1 : 0; } else if (isEmpty(b)) { return 0; } final int minLen = N.min(a.length, b.length); if (minLen > MISMATCH_THRESHOLD) { return Arrays.mismatch(a, b); } for (int i = 0; i < minLen; i++) { if (a[i] != b[i]) { return i; } } return a.length == b.length ? -1 : minLen; } /** * Finds and returns the index of the first mismatch between two byte arrays starting from specified indices. * If the arrays are identical in the specified range, returns -1. * * @param a the first byte array * @param fromIndexA the starting index in the first array * @param b the second byte array * @param fromIndexB the starting index in the second array * @param len the number of elements to compare * @return the index of the first mismatch, or -1 if the arrays are identical in the specified range * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the starting indices or length are out of bounds * @see Arrays#mismatch(byte[], int, int, byte[], int, int) */ public static int mismatch(final byte[] a, final int fromIndexA, final byte[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return -1; } if (len > MISMATCH_THRESHOLD) { return Arrays.mismatch(a, fromIndexA, fromIndexA + len, b, fromIndexB, fromIndexB + len); } for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (a[i] != b[j]) { return i - fromIndexA; } } return -1; } /** * Finds and returns the index of the first mismatch between two arrays. * If the arrays are identical or both are {@code null} or empty, returns -1. * * @param a the first short array * @param b the second short array * @return the index of the first mismatch, or -1 if the arrays are identical or both are {@code null} or empty. * @see Arrays#mismatch(short[], short[]) */ public static int mismatch(final short[] a, final short[] b) { if (a == b) { return -1; } if (isEmpty(a)) { return isEmpty(b) ? -1 : 0; } else if (isEmpty(b)) { return 0; } final int minLen = N.min(a.length, b.length); if (minLen > MISMATCH_THRESHOLD) { return Arrays.mismatch(a, b); } for (int i = 0; i < minLen; i++) { if (a[i] != b[i]) { return i; } } return a.length == b.length ? -1 : minLen; } /** * Finds and returns the index of the first mismatch between two short arrays starting from specified indices. * If the arrays are identical in the specified range, returns -1. * * @param a the first short array * @param fromIndexA the starting index in the first array * @param b the second short array * @param fromIndexB the starting index in the second array * @param len the number of elements to compare * @return the index of the first mismatch, or -1 if the arrays are identical in the specified range * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the starting indices or length are out of bounds * @see Arrays#mismatch(short[], int, int, short[], int, int) */ public static int mismatch(final short[] a, final int fromIndexA, final short[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return -1; } if (len > MISMATCH_THRESHOLD) { return Arrays.mismatch(a, fromIndexA, fromIndexA + len, b, fromIndexB, fromIndexB + len); } for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (a[i] != b[j]) { return i - fromIndexA; } } return -1; } /** * Finds and returns the index of the first mismatch between two arrays. * If the arrays are identical or both are {@code null} or empty, returns -1. * * @param a the first int array * @param b the second int array * @return the index of the first mismatch, or -1 if the arrays are identical or both are {@code null} or empty. * @see Arrays#mismatch(int[], int[]) */ public static int mismatch(final int[] a, final int[] b) { if (a == b) { return -1; } if (isEmpty(a)) { return isEmpty(b) ? -1 : 0; } else if (isEmpty(b)) { return 0; } final int minLen = N.min(a.length, b.length); if (minLen > MISMATCH_THRESHOLD) { return Arrays.mismatch(a, b); } for (int i = 0; i < minLen; i++) { if (a[i] != b[i]) { return i; } } return a.length == b.length ? -1 : minLen; } /** * Finds and returns the index of the first mismatch between two int arrays starting from specified indices. * If the arrays are identical in the specified range, returns -1. * * @param a the first int array * @param fromIndexA the starting index in the first array * @param b the second int array * @param fromIndexB the starting index in the second array * @param len the number of elements to compare * @return the index of the first mismatch, or -1 if the arrays are identical in the specified range * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the starting indices or length are out of bounds * @see Arrays#mismatch(int[], int, int, int[], int, int) */ public static int mismatch(final int[] a, final int fromIndexA, final int[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return -1; } if (len > MISMATCH_THRESHOLD) { return Arrays.mismatch(a, fromIndexA, fromIndexA + len, b, fromIndexB, fromIndexB + len); } for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (a[i] != b[j]) { return i - fromIndexA; } } return -1; } /** * Finds and returns the index of the first mismatch between two arrays. * If the arrays are identical or both are {@code null} or empty, returns -1. * * @param a the first long array * @param b the second long array * @return the index of the first mismatch, or -1 if the arrays are identical or both are {@code null} or empty. * @see Arrays#mismatch(long[], long[]) */ public static int mismatch(final long[] a, final long[] b) { if (a == b) { return -1; } if (isEmpty(a)) { return isEmpty(b) ? -1 : 0; } else if (isEmpty(b)) { return 0; } final int minLen = N.min(a.length, b.length); if (minLen > MISMATCH_THRESHOLD) { return Arrays.mismatch(a, b); } for (int i = 0; i < minLen; i++) { if (a[i] != b[i]) { return i; } } return a.length == b.length ? -1 : minLen; } /** * Finds and returns the index of the first mismatch between two long arrays starting from specified indices. * If the arrays are identical in the specified range, returns -1. * * @param a the first long array * @param fromIndexA the starting index in the first array * @param b the second long array * @param fromIndexB the starting index in the second array * @param len the number of elements to compare * @return the index of the first mismatch, or -1 if the arrays are identical in the specified range * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the starting indices or length are out of bounds * @see Arrays#mismatch(long[], int, int, long[], int, int) */ public static int mismatch(final long[] a, final int fromIndexA, final long[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return -1; } if (len > MISMATCH_THRESHOLD) { return Arrays.mismatch(a, fromIndexA, fromIndexA + len, b, fromIndexB, fromIndexB + len); } for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (a[i] != b[j]) { return i - fromIndexA; } } return -1; } /** * Finds and returns the index of the first mismatch between two arrays. * If the arrays are identical or both are {@code null} or empty, returns -1. * * @param a the first float array * @param b the second float array * @return the index of the first mismatch, or -1 if the arrays are identical or both are {@code null} or empty. * @see Arrays#mismatch(float[], float[]) */ public static int mismatch(final float[] a, final float[] b) { if (a == b) { return -1; } if (isEmpty(a)) { return isEmpty(b) ? -1 : 0; } else if (isEmpty(b)) { return 0; } final int minLen = N.min(a.length, b.length); if (minLen > MISMATCH_THRESHOLD) { return Arrays.mismatch(a, b); } for (int i = 0; i < minLen; i++) { if (Float.compare(a[i], b[i]) != 0) { return i; } } return a.length == b.length ? -1 : minLen; } /** * Finds and returns the index of the first mismatch between two float arrays starting from specified indices. * If the arrays are identical in the specified range, returns -1. * * @param a the first float array * @param fromIndexA the starting index in the first array * @param b the second float array * @param fromIndexB the starting index in the second array * @param len the number of elements to compare * @return the index of the first mismatch, or -1 if the arrays are identical in the specified range * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the starting indices or length are out of bounds * @see Arrays#mismatch(float[], int, int, float[], int, int) */ public static int mismatch(final float[] a, final int fromIndexA, final float[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return -1; } if (len > MISMATCH_THRESHOLD) { return Arrays.mismatch(a, fromIndexA, fromIndexA + len, b, fromIndexB, fromIndexB + len); } for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (Float.compare(a[i], b[j]) != 0) { return i - fromIndexA; } } return -1; } /** * Finds and returns the index of the first mismatch between two arrays. * If the arrays are identical or both are {@code null} or empty, returns -1. * * @param a the first double array * @param b the second double array * @return the index of the first mismatch, or -1 if the arrays are identical or both are {@code null} or empty. * @see Arrays#mismatch(double[], double[]) */ public static int mismatch(final double[] a, final double[] b) { if (a == b) { return -1; } if (isEmpty(a)) { return isEmpty(b) ? -1 : 0; } else if (isEmpty(b)) { return 0; } final int minLen = N.min(a.length, b.length); if (minLen > MISMATCH_THRESHOLD) { return Arrays.mismatch(a, b); } for (int i = 0; i < minLen; i++) { if (Double.compare(a[i], b[i]) != 0) { return i; } } return a.length == b.length ? -1 : minLen; } /** * Finds and returns the index of the first mismatch between two double arrays starting from specified indices. * If the arrays are identical in the specified range, returns -1. * * @param a the first double array * @param fromIndexA the starting index in the first array * @param b the second double array * @param fromIndexB the starting index in the second array * @param len the number of elements to compare * @return the index of the first mismatch, or -1 if the arrays are identical in the specified range * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the starting indices or length are out of bounds * @see Arrays#mismatch(double[], int, int, double[], int, int) */ public static int mismatch(final double[] a, final int fromIndexA, final double[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return -1; } if (len > MISMATCH_THRESHOLD) { return Arrays.mismatch(a, fromIndexA, fromIndexA + len, b, fromIndexB, fromIndexB + len); } for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (Double.compare(a[i], b[j]) != 0) { return i - fromIndexA; } } return -1; } /** * Finds and returns the index of the first mismatch between two arrays. * If the arrays are identical or both are {@code null} or empty, returns -1. * * @param the type of elements in the arrays, which must be Comparable * @param a the first array * @param b the second array * @return the index of the first mismatch, or -1 if the arrays are identical or both are {@code null} or empty. * @see Arrays#mismatch(Object[], Object[]) */ public static > int mismatch(final T[] a, final T[] b) { return mismatch(a, b, NATURAL_COMPARATOR); } /** * Finds and returns the index of the first mismatch between two arrays starting from specified indices. * If the arrays are identical in the specified range, returns -1. * * @param a the first array * @param fromIndexA the starting index in the first array * @param b the second array * @param fromIndexB the starting index in the second array * @param len the number of elements to compare * @return the index of the first mismatch, or -1 if the arrays are identical in the specified range * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the starting indices or length are out of bounds * @see Arrays#mismatch(Object[], int, int, Object[], int, int) */ public static > int mismatch(final T[] a, final int fromIndexA, final T[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { return mismatch(a, fromIndexA, b, fromIndexB, len, NATURAL_COMPARATOR); } /** * Finds and returns the index of the first mismatch between two arrays. * If the arrays are identical or both are {@code null} or empty, returns -1. * * @param the type of elements in the arrays, which must be Comparable * @param a the first array * @param b the second array * @param cmp the comparator to compare array elements * @return the index of the first mismatch, or -1 if the arrays are identical or both are {@code null} or empty. * @see Arrays#mismatch(Object[], Object[], Comparator) */ public static int mismatch(final T[] a, final T[] b, Comparator cmp) { if (a == b) { return -1; } if (isEmpty(a)) { return isEmpty(b) ? -1 : 0; } else if (isEmpty(b)) { return 0; } cmp = checkComparator(cmp); final int minLen = N.min(a.length, b.length); for (int i = 0; i < minLen; i++) { if (cmp.compare(a[i], b[i]) != 0) { return i; } } return a.length == b.length ? -1 : minLen; } /** * Finds and returns the index of the first mismatch between two arrays starting from specified indices. * If the arrays are identical in the specified range, returns -1. * * @param a the first array * @param fromIndexA the starting index in the first array * @param b the second array * @param fromIndexB the starting index in the second array * @param len the number of elements to compare * @param cmp the comparator to compare array elements * @return the index of the first mismatch, or -1 if the arrays are identical in the specified range * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the starting indices or length are out of bounds * @see Arrays#mismatch(Object[], int, int, Object[], int, int, Comparator) */ public static int mismatch(final T[] a, final int fromIndexA, final T[] b, final int fromIndexB, final int len, Comparator cmp) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return -1; } cmp = checkComparator(cmp); for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (cmp.compare(a[i], b[j]) != 0) { return i - fromIndexA; } } return -1; } /** * Finds and returns the index of the first mismatch between two collections starting from specified indices. * If the collections are identical in the specified range, returns -1. * * @param the type of elements in the collections * @param a the first collection * @param fromIndexA the starting index in the first collection * @param b the second collection * @param fromIndexB the starting index in the second collection * @param len the number of elements to compare * @return the index of the first mismatch, or -1 if the collections are identical in the specified range * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the starting indices or length are out of bounds * @see Arrays#mismatch(Object[], int, int, Object[], int, int) */ public static int mismatch(final Collection a, final int fromIndexA, final Collection b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { return mismatch(a, fromIndexA, b, fromIndexB, len, NATURAL_COMPARATOR); } /** * Finds and returns the index of the first mismatch between two iterables. * If the iterables are identical or both are {@code null} or empty, returns -1. * * @param the type of elements in the iterables * @param a the first iterable * @param b the second iterable * @return the index of the first mismatch, or -1 if the iterables are identical or both are {@code null} or empty * @see Arrays#mismatch(Object[], Object[]) */ public static > int mismatch(final Iterable a, final Iterable b) { return mismatch(a, b, NATURAL_COMPARATOR); } /** * Finds and returns the index of the first mismatch between two iterators. * If the iterators are identical or both are {@code null} or empty, returns -1. * * @param the type of elements in the iterators * @param a the first iterator * @param b the second iterator * @return the index of the first mismatch, or -1 if the iterators are identical or both are {@code null} or empty * @see Arrays#mismatch(Object[], Object[]) */ public static > int mismatch(final Iterator a, final Iterator b) { return mismatch(a, b, NATURAL_COMPARATOR); } /** * Finds and returns the index of the first mismatch between two collections starting from specified indices. * If the collections are identical in the specified range, returns -1. * * @param the type of elements in the collections * @param a the first collection * @param fromIndexA the starting index in the first collection * @param b the second collection * @param fromIndexB the starting index in the second collection * @param len the number of elements to compare * @param cmp the comparator to compare elements * @return the index of the first mismatch, or -1 if the collections are identical in the specified range * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the starting indices or length are out of bounds * @see Arrays#mismatch(Object[], int, int, Object[], int, int, Comparator) */ public static int mismatch(final Collection a, int fromIndexA, final Collection b, int fromIndexB, final int len, Comparator cmp) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, size(a)); checkFromIndexSize(fromIndexB, len, size(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return -1; } cmp = checkComparator(cmp); final Iterator iterA = a.iterator(); final Iterator iterB = b.iterator(); while (fromIndexA-- > 0) { iterA.next(); } while (fromIndexB-- > 0) { iterB.next(); } for (int i = 0; i < len; i++) { if (cmp.compare(iterA.next(), iterB.next()) != 0) { return i; } } return -1; } /** * Finds and returns the index of the first mismatch between two iterables using the specified comparator. * If the iterables are identical or both are {@code null} or empty, returns -1. * * @param the type of elements in the iterables * @param a the first iterable * @param b the second iterable * @param cmp the comparator to compare elements * @return the index of the first mismatch, or -1 if the iterables are identical or both are {@code null} or empty * @see Arrays#mismatch(Object[], Object[], Comparator) */ public static int mismatch(final Iterable a, final Iterable b, final Comparator cmp) { if (a == b) { return -1; } if (isEmpty(a)) { return isEmpty(b) ? -1 : 0; } else if (isEmpty(b)) { return 0; } return mismatch(a.iterator(), b.iterator(), cmp); } /** * Finds and returns the index of the first mismatch between two iterators using the specified comparator. * If the iterators are identical or both are {@code null} or empty, returns -1. * * @param the type of elements in the iterators * @param a the first iterator * @param b the second iterator * @param cmp the comparator to compare elements * @return the index of the first mismatch, or -1 if the iterators are identical or both are {@code null} or empty * @see Arrays#mismatch(Object[], Object[], Comparator) */ public static int mismatch(final Iterator a, final Iterator b, Comparator cmp) { if (a == b) { return -1; } if (isEmpty(a)) { return isEmpty(b) ? -1 : 0; } else if (isEmpty(b)) { return 0; } cmp = checkComparator(cmp); // a == null ? ObjIterator.empty() : a; // b == null ? ObjIterator.empty() : b; int idx = 0; while (a.hasNext() && b.hasNext()) { if (cmp.compare(a.next(), b.next()) != 0) { return idx; } idx++; } return a.hasNext() || b.hasNext() ? idx : -1; } /** * Returns default Comparator {@code NATURAL_COMPARATOR} if the specified {@code cmp} is {@code null}. Otherwise returns {@code cmp}. * * @param * @param cmp * @return */ static Comparator checkComparator(final Comparator cmp) { return cmp == null ? NATURAL_COMPARATOR : cmp; } /** * Compares two comparable objects to determine if the first is less than the second. ({@code null} is considered as the smallest value in nature order). * * @param the type of the objects being compared, which must be comparable * @param a the first object to compare, must not be null * @param b the second object to compare, must not be null * @return {@code true} if the first object is less than the second, {@code false} otherwise */ public static > boolean lessThan(final T a, final T b) { return compare(a, b) < 0; } /** * Compares two objects using the specified comparator to determine if the first is less than the second. * * @param the type of the objects being compared * @param a the first object to compare, must not be null * @param b the second object to compare, must not be null * @param cmp the comparator to use for comparison, if {@code null}, the natural ordering of the objects will be used * @return {@code true} if the first object is less than the second, {@code false} otherwise */ public static boolean lessThan(final T a, final T b, Comparator cmp) { cmp = checkComparator(cmp); return cmp.compare(a, b) < 0; } /** * Compares two comparable objects to determine if the first is less than or equal to the second. ({@code null} is considered as the smallest value in nature order). * * @param the type of the objects being compared, which must be comparable * @param a the first object to compare, must not be null * @param b the second object to compare, must not be null * @return {@code true} if the first object is less than or equal to the second, {@code false} otherwise */ public static > boolean lessEqual(final T a, final T b) { return compare(a, b) <= 0; } /** * Compares two objects using the specified comparator to determine if the first is less than or equal to the second. * * @param the type of the objects being compared * @param a the first object to compare, must not be null * @param b the second object to compare, must not be null * @param cmp the comparator to use for comparison, if {@code null}, the natural ordering of the objects will be used * @return {@code true} if the first object is less than or equal to the second, {@code false} otherwise */ public static boolean lessEqual(final T a, final T b, Comparator cmp) { cmp = checkComparator(cmp); return cmp.compare(a, b) <= 0; } /** * Compares two comparable objects to determine if the first is greater than the second. ({@code null} is considered as the smallest value in nature order). * * @param the type of the objects being compared, which must be comparable * @param a the first object to compare, must not be null * @param b the second object to compare, must not be null * @return {@code true} if the first object is greater than the second, {@code false} otherwise */ public static > boolean greaterThan(final T a, final T b) { return compare(a, b) > 0; } /** * Compares two objects using the specified comparator to determine if the first is greater than the second. * * @param the type of the objects being compared * @param a the first object to compare, must not be null * @param b the second object to compare, must not be null * @param cmp the comparator to use for comparison, if {@code null}, the natural ordering of the objects will be used * @return {@code true} if the first object is greater than the second, {@code false} otherwise */ public static boolean greaterThan(final T a, final T b, Comparator cmp) { cmp = checkComparator(cmp); return cmp.compare(a, b) > 0; } /** * Compares two comparable objects to determine if the first is greater than or equal to the second. ({@code null} is considered as the smallest value in nature order). * * @param the type of the objects being compared, which must be comparable * @param a the first object to compare, must not be null * @param b the second object to compare, must not be null * @return {@code true} if the first object is greater than or equal to the second, {@code false} otherwise */ public static > boolean greaterEqual(final T a, final T b) { return compare(a, b) >= 0; } /** * Compares two objects using the specified comparator to determine if the first is greater than or equal to the second. * * @param the type of the objects being compared * @param a the first object to compare, must not be null * @param b the second object to compare, must not be null * @param cmp the comparator to use for comparison, if {@code null}, the natural ordering of the objects will be used * @return {@code true} if the first object is greater than or equal to the second, {@code false} otherwise */ public static boolean greaterEqual(final T a, final T b, Comparator cmp) { cmp = checkComparator(cmp); return cmp.compare(a, b) >= 0; } /** * Checks if the given value is greater than the minimum value and less than the maximum value. ({@code null} is considered as the smallest value in nature order). * * @param the type of the objects being compared, which must be comparable * @param value the value to check, must not be null * @param min the minimum value, must not be null * @param max the maximum value, must not be null * @return {@code true} if the value is greater than the minimum and less than the maximum, {@code false} otherwise */ public static > boolean gtAndLt(final T value, final T min, final T max) { if (compare(value, min) <= 0) { return false; } return compare(value, max) < 0; } /** * Checks if the given value is greater than the minimum value and less than the maximum value using the specified comparator. * * @param the type of the objects being compared * @param value the value to check, must not be null * @param min the minimum value, must not be null * @param max the maximum value, must not be null * @param cmp the comparator to use for comparison, if {@code null}, the natural ordering of the objects will be used * @return {@code true} if the value is greater than the minimum and less than the maximum, {@code false} otherwise */ public static boolean gtAndLt(final T value, final T min, final T max, Comparator cmp) { cmp = checkComparator(cmp); if (cmp.compare(value, min) <= 0) { return false; } return cmp.compare(value, max) < 0; } /** * Checks if the given value is greater than or equal to the minimum value and less than the maximum value. ({@code null} is considered as the smallest value in nature order). * * @param the type of the objects being compared, which must be comparable * @param value the value to check, must not be null * @param min the minimum value, must not be null * @param max the maximum value, must not be null * @return {@code true} if the value is greater than or equal to the minimum and less than the maximum, {@code false} otherwise */ public static > boolean geAndLt(final T value, final T min, final T max) { if (compare(value, min) < 0) { return false; } return compare(value, max) < 0; } /** * Checks if the given value is greater than or equal to the minimum value and less than the maximum value using the specified comparator. * * @param the type of the objects being compared * @param value the value to check, must not be null * @param min the minimum value, must not be null * @param max the maximum value, must not be null * @param cmp the comparator to use for comparison, if {@code null}, the natural ordering of the objects will be used * @return {@code true} if the value is greater than or equal to the minimum and less than the maximum, {@code false} otherwise */ public static boolean geAndLt(final T value, final T min, final T max, Comparator cmp) { cmp = checkComparator(cmp); if (cmp.compare(value, min) < 0) { return false; } return cmp.compare(value, max) < 0; } /** * Checks if the given value is greater than or equal to the minimum value and less than or equal to the maximum value. ({@code null} is considered as the smallest value in nature order). * * @param the type of the objects being compared, which must be comparable * @param value the value to check, must not be null * @param min the minimum value, must not be null * @param max the maximum value, must not be null * @return {@code true} if the value is greater than or equal to the minimum and less than or equal to the maximum, {@code false} otherwise */ public static > boolean geAndLe(final T value, final T min, final T max) { if (compare(value, min) < 0) { return false; } return compare(value, max) <= 0; } /** * Checks if the given value is greater than or equal to the minimum value and less than or equal to the maximum value using the specified comparator. * * @param the type of the objects being compared * @param value the value to check, must not be null * @param min the minimum value, must not be null * @param max the maximum value, must not be null * @param cmp the comparator to use for comparison, if {@code null}, the natural ordering of the objects will be used * @return {@code true} if the value is greater than or equal to the minimum and less than or equal to the maximum, {@code false} otherwise */ public static boolean geAndLe(final T value, final T min, final T max, Comparator cmp) { cmp = checkComparator(cmp); if (cmp.compare(value, min) < 0) { return false; } return cmp.compare(value, max) <= 0; } /** * Checks if the given value is greater than the minimum value and less than or equal to the maximum value. ({@code null} is considered as the smallest value in nature order). * * @param the type of the objects being compared, which must be comparable * @param value the value to check, must not be null * @param min the minimum value, must not be null * @param max the maximum value, must not be null * @return {@code true} if the value is greater than the minimum and less than or equal to the maximum, {@code false} otherwise */ public static > boolean gtAndLe(final T value, final T min, final T max) { if (compare(value, min) <= 0) { return false; } return compare(value, max) <= 0; } /** * Checks if the given value is greater than the minimum value and less than or equal to the maximum value using the specified comparator. * * @param the type of the objects being compared * @param value the value to check, must not be null * @param min the minimum value, must not be null * @param max the maximum value, must not be null * @param cmp the comparator to use for comparison, if {@code null}, the natural ordering of the objects will be used * @return {@code true} if the value is greater than the minimum and less than or equal to the maximum, {@code false} otherwise */ public static boolean gtAndLe(final T value, final T min, final T max, Comparator cmp) { cmp = checkComparator(cmp); if (cmp.compare(value, min) <= 0) { return false; } return cmp.compare(value, max) <= 0; } /** * Checks if the given value is between the specified minimum and maximum values, inclusive. * It means {@code min <= value <= max}. * {@code null} is considered as the smallest value in nature order. * @implNote it is equivalent to {@link #geAndLe(Comparable, Comparable, Comparable)}. * * @param the type of the objects being compared * @param value the value to check, must not be null * @param min the minimum value, must not be null * @param max the maximum value, must not be null * @return {@code true} if the value is between the minimum and maximum values, inclusive; {@code false} otherwise * @deprecated Use {@link #geAndLe(Comparable, Comparable, Comparable)} instead. */ @Deprecated public static > boolean isBetween(final T value, final T min, final T max) { return geAndLe(value, min, max); } /** * Checks if the given value is between the specified minimum and maximum values, inclusive. * It means {@code min <= value <= max}. * @implNote it is equivalent to {@link #geAndLe(Object, Object, Object, Comparator)}. * * @param the type of the objects being compared * @param value the value to check, must not be null * @param min the minimum value, must not be null * @param max the maximum value, must not be null * @param cmp the comparator to compare the values, must not be null * @return {@code true} if the value is between the minimum and maximum values, inclusive; {@code false} otherwise * @deprecated Use {@link #geAndLe(Object, Object, Object, Comparator)} instead. */ @Deprecated public static boolean isBetween(final T value, final T min, final T max, final Comparator cmp) { return geAndLe(value, min, max, cmp); } /** * Compares two boolean values for equality. * * @param a the first boolean value * @param b the second boolean value * @return {@code true} if the boolean values are equal, {@code false} otherwise */ public static boolean equals(final boolean a, final boolean b) { return a == b; } /** * Compares two char values for equality. * * @param a the first char value * @param b the second char value * @return {@code true} if the char values are equal, {@code false} otherwise */ public static boolean equals(final char a, final char b) { return a == b; } /** * Compares two byte values for equality. * * @param a the first byte value * @param b the second byte value * @return {@code true} if the byte values are equal, {@code false} otherwise */ public static boolean equals(final byte a, final byte b) { return a == b; } /** * Compares two short values for equality. * * @param a the first short value * @param b the second short value * @return {@code true} if the short values are equal, {@code false} otherwise */ public static boolean equals(final short a, final short b) { return a == b; } /** * Compares two int values for equality. * * @param a the first int value * @param b the second int value * @return {@code true} if the int values are equal, {@code false} otherwise */ public static boolean equals(final int a, final int b) { return a == b; } /** * Compares two long values for equality. * * @param a the first long value * @param b the second long value * @return {@code true} if the long values are equal, {@code false} otherwise */ public static boolean equals(final long a, final long b) { return a == b; } /** * Compares two float values for equality. * * @param a the first float value * @param b the second float value * @return {@code true} if the float values are equal, {@code false} otherwise */ public static boolean equals(final float a, final float b) { return Float.compare(a, b) == 0; } /** * Compares two double values for equality. * * @param a the first double value * @param b the second double value * @return {@code true} if the double values are equal, {@code false} otherwise */ public static boolean equals(final double a, final double b) { return Double.compare(a, b) == 0; } /** * Compares two strings for equality. * * @param a the first string * @param b the second string * @return {@code true} if the strings are equal, {@code false} otherwise */ public static boolean equals(final String a, final String b) { return (a == null) ? b == null : (b != null && a.length() == b.length() && a.equals(b)); } /** * Compares two strings for equality, ignoring case. * * @param a the first string * @param b the second string * @return {@code true} if the strings are equal, {@code false} otherwise */ public static boolean equalsIgnoreCase(final String a, final String b) { return (a == null) ? b == null : (a.equalsIgnoreCase(b)); } /** * Compares two objects for equality. If the objects are arrays, the appropriate {@code Arrays.equals} method will be used. * * @param a the first object * @param b the second object * @return {@code true} if the objects are equal, {@code false} otherwise */ public static boolean equals(final Object a, final Object b) { if (Objects.equals(a, b)) { return true; } if ((a != null) && (b != null)) { final Type typeA = typeOf(a.getClass()); if (typeA.isPrimitiveArray()) { final Type typeB = typeOf(b.getClass()); return typeA.clazz().equals(typeB.clazz()) && typeA.equals(a, b); } else if (typeA.isObjectArray()) { final Type typeB = typeOf(b.getClass()); return typeB.isObjectArray() && typeA.equals(a, b); } } return false; } /** * Compares two arrays for equality. * * @param a the first array * @param b the second array * @return {@code true} if the arrays are equal, {@code false} otherwise * @see Arrays#equals(boolean[], boolean[]) */ public static boolean equals(final boolean[] a, final boolean[] b) { return Arrays.equals(a, b); } /** * Compares two boolean arrays for equality within the specified range. * * @param a the first boolean array, must not be null * @param fromIndexA the starting index in the first array, inclusive * @param b the second boolean array, must not be null * @param fromIndexB the starting index in the second array, inclusive * @param len the number of elements to compare * @return {@code true} if the specified range of elements in both arrays are equal, {@code false} otherwise * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified range is out of bounds * @see Arrays#equals(boolean[], boolean[]) */ public static boolean equals(final boolean[] a, final int fromIndexA, final boolean[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return true; } for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (a[i] != b[j]) { return false; } } return true; } /** * Compares two arrays for equality. * * @param a the first array * @param b the second array * @return {@code true} if the arrays are equal, {@code false} otherwise * @see Arrays#equals(char[], char[]) */ public static boolean equals(final char[] a, final char[] b) { return Arrays.equals(a, b); } /** * Compares two char arrays for equality within the specified range. * * @param a the first char array, must not be null * @param fromIndexA the starting index in the first array, inclusive * @param b the second char array, must not be null * @param fromIndexB the starting index in the second array, inclusive * @param len the number of elements to compare * @return {@code true} if the specified range of elements in both arrays are equal, {@code false} otherwise * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified range is out of bounds * @see Arrays#equals(char[], char[]) */ public static boolean equals(final char[] a, final int fromIndexA, final char[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return true; } for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (a[i] != b[j]) { return false; } } return true; } /** * Compares two arrays for equality. * * @param a the first array * @param b the second array * @return {@code true} if the arrays are equal, {@code false} otherwise * @see Arrays#equals(byte[], byte[]) */ public static boolean equals(final byte[] a, final byte[] b) { return Arrays.equals(a, b); } /** * Compares two byte arrays for equality within the specified range. * * @param a the first byte array, must not be null * @param fromIndexA the starting index in the first array, inclusive * @param b the second byte array, must not be null * @param fromIndexB the starting index in the second array, inclusive * @param len the number of elements to compare * @return {@code true} if the specified range of elements in both arrays are equal, {@code false} otherwise * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified range is out of bounds * @see Arrays#equals(byte[], byte[]) */ public static boolean equals(final byte[] a, final int fromIndexA, final byte[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return true; } for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (a[i] != b[j]) { return false; } } return true; } /** * Compares two arrays for equality. * * @param a the first array * @param b the second array * @return {@code true} if the arrays are equal, {@code false} otherwise * @see Arrays#equals(short[], short[]) */ public static boolean equals(final short[] a, final short[] b) { return Arrays.equals(a, b); } /** * Compares two short arrays for equality within the specified range. * * @param a the first short array, must not be null * @param fromIndexA the starting index in the first array, inclusive * @param b the second short array, must not be null * @param fromIndexB the starting index in the second array, inclusive * @param len the number of elements to compare * @return {@code true} if the specified range of elements in both arrays are equal, {@code false} otherwise * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified range is out of bounds * @see Arrays#equals(short[], short[]) */ public static boolean equals(final short[] a, final int fromIndexA, final short[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return true; } for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (a[i] != b[j]) { return false; } } return true; } /** * Compares two arrays for equality. * * @param a the first array * @param b the second array * @return {@code true} if the arrays are equal, {@code false} otherwise * @see Arrays#equals(int[], int[]) */ public static boolean equals(final int[] a, final int[] b) { return Arrays.equals(a, b); } /** * Compares two int arrays for equality within the specified range. * * @param a the first int array, must not be null * @param fromIndexA the starting index in the first array, inclusive * @param b the second int array, must not be null * @param fromIndexB the starting index in the second array, inclusive * @param len the number of elements to compare * @return {@code true} if the specified range of elements in both arrays are equal, {@code false} otherwise * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified range is out of bounds * @see Arrays#equals(int[], int[]) */ public static boolean equals(final int[] a, final int fromIndexA, final int[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return true; } for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (a[i] != b[j]) { return false; } } return true; } /** * Compares two arrays for equality. * * @param a the first array * @param b the second array * @return {@code true} if the arrays are equal, {@code false} otherwise * @see Arrays#equals(long[], long[]) */ public static boolean equals(final long[] a, final long[] b) { return Arrays.equals(a, b); } /** * Compares two long arrays for equality within the specified range. * * @param a the first long array, must not be null * @param fromIndexA the starting index in the first array, inclusive * @param b the second long array, must not be null * @param fromIndexB the starting index in the second array, inclusive * @param len the number of elements to compare * @return {@code true} if the specified range of elements in both arrays are equal, {@code false} otherwise * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified range is out of bounds * @see Arrays#equals(long[], long[]) */ public static boolean equals(final long[] a, final int fromIndexA, final long[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return true; } for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (a[i] != b[j]) { return false; } } return true; } /** * Compares two arrays for equality. * * @param a the first array * @param b the second array * @return {@code true} if the arrays are equal, {@code false} otherwise * @see Arrays#equals(float[], float[]) */ public static boolean equals(final float[] a, final float[] b) { return Arrays.equals(a, b); } /** * Compares two float arrays for equality within the specified range. * * @param a the first float array, must not be null * @param fromIndexA the starting index in the first array, inclusive * @param b the second float array, must not be null * @param fromIndexB the starting index in the second array, inclusive * @param len the number of elements to compare * @return {@code true} if the specified range of elements in both arrays are equal, {@code false} otherwise * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified range is out of bounds * @see Arrays#equals(float[], float[]) */ public static boolean equals(final float[] a, final int fromIndexA, final float[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return true; } for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (Float.compare(a[i], b[j]) != 0) { return false; } } return true; } /** * Compares two arrays for equality. * * @param a the first array * @param b the second array * @return {@code true} if the arrays are equal, {@code false} otherwise * @see Arrays#equals(double[], double[]) */ public static boolean equals(final double[] a, final double[] b) { return Arrays.equals(a, b); } /** * Compares two double arrays for equality within the specified range. * * @param a the first double array, must not be null * @param fromIndexA the starting index in the first array, inclusive * @param b the second double array, must not be null * @param fromIndexB the starting index in the second array, inclusive * @param len the number of elements to compare * @return {@code true} if the specified range of elements in both arrays are equal, {@code false} otherwise * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified range is out of bounds * @see Arrays#equals(double[], double[]) */ public static boolean equals(final double[] a, final int fromIndexA, final double[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return true; } for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (Double.compare(a[i], b[j]) != 0) { return false; } } return true; } /** * Compares two arrays for equality. * * @param a the first array * @param b the second array * @return {@code true} if the arrays are equal, {@code false} otherwise * @see Arrays#equals(Object[], Object[]) */ public static boolean equals(final Object[] a, final Object[] b) { return a == b || (a != null && b != null && a.length == b.length && equals(a, 0, b, 0, a.length)); } /** * Compares two arrays for equality within the specified range. * * @param a the first array, must not be null * @param fromIndexA the starting index in the first array, inclusive * @param b the second array, must not be null * @param fromIndexB the starting index in the second array, inclusive * @param len the number of elements to compare * @return {@code true} if the specified range of elements in both arrays are equal, {@code false} otherwise * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified range is out of bounds * @see Arrays#equals(Object[], Object[]) */ public static boolean equals(final Object[] a, final int fromIndexA, final Object[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return true; } else if (!a.getClass().equals(b.getClass())) { return false; } for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (!equals(a[i], b[j])) { return false; } } return true; } /** * Compares two objects for equality. If the objects are arrays, the appropriate {@code Arrays.deepEquals} method will be used. * * @param a the first object to compare, which may be null * @param b the second object to compare, which may be null * @return {@code true} if the objects are deeply equal, {@code false} otherwise * @see Arrays#deepEquals(Object[], Object[]) */ public static boolean deepEquals(final Object a, final Object b) { if (Objects.equals(a, b)) { return true; } final Class cls = a == null ? null : a.getClass(); if ((a != null) && (b != null) && cls.isArray() && cls.equals(b.getClass())) { final Integer enumInt = CLASS_TYPE_ENUM.get(cls); if (enumInt == null) { return deepEquals((Object[]) a, (Object[]) b); } switch (enumInt) { case 11: return equals((boolean[]) a, (boolean[]) b); case 12: return equals((char[]) a, (char[]) b); case 13: return equals((byte[]) a, (byte[]) b); case 14: return equals((short[]) a, (short[]) b); case 15: return equals((int[]) a, (int[]) b); case 16: return equals((long[]) a, (long[]) b); case 17: return equals((float[]) a, (float[]) b); case 18: return equals((double[]) a, (double[]) b); case 19: return equals((String[]) a, (String[]) b); default: return deepEquals((Object[]) a, (Object[]) b); } } return false; } /** * Compares two arrays for deep equality. * * @param a the first array * @param b the second array * @return {@code true} if the arrays are equal, {@code false} otherwise * @see Arrays#deepEquals(Object[], Object[]) */ public static boolean deepEquals(final Object[] a, final Object[] b) { return a == b || (a != null && b != null && a.length == b.length && deepEquals(a, 0, b, 0, a.length)); } /** * Compares two arrays for deep equality within the specified range. * * @param a the first array, must not be null * @param fromIndexA the starting index in the first array, inclusive * @param b the second array, must not be null * @param fromIndexB the starting index in the second array, inclusive * @param len the number of elements to compare * @return {@code true} if the specified range of elements in both arrays are equal, {@code false} otherwise * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified range is out of bounds * @see Arrays#deepEquals(Object[], Object[]) */ public static boolean deepEquals(final Object[] a, final int fromIndexA, final Object[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return true; } else if (!a.getClass().equals(b.getClass())) { return false; } for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (!deepEquals(a[i], b[j])) { return false; } } return true; } /** * Compares two arrays of Strings, ignoring case considerations. * * @param a the first array of Strings to compare, which may be null * @param b the second array of Strings to compare, which may be null * @return {@code true} if the arrays are equal, ignoring case considerations, or both are null; {@code false} otherwise */ public static boolean equalsIgnoreCase(final String[] a, final String[] b) { return (a == null || b == null) ? a == b : (a.length == b.length && equalsIgnoreCase(a, 0, b, 0, a.length)); } /** * Compares two arrays of Strings, ignoring case considerations, within the specified range. * * @param a the first array of Strings to compare, which may be null * @param fromIndexA the starting index in the first array, inclusive * @param b the second array of Strings to compare, which may be null * @param fromIndexB the starting index in the second array, inclusive * @param len the number of elements to compare * @return {@code true} if the specified range of elements in both arrays are equal, ignoring case considerations, or both are null; {@code false} otherwise * @throws IllegalArgumentException if the length is negative * @throws IndexOutOfBoundsException if the specified range is out of bounds */ public static boolean equalsIgnoreCase(final String[] a, final int fromIndexA, final String[] b, final int fromIndexB, final int len) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNegative(len, cs.len); checkFromIndexSize(fromIndexA, len, len(a)); // NOSONAR checkFromIndexSize(fromIndexB, len, len(b)); if ((fromIndexA == fromIndexB && a == b) || len == 0) { return true; } for (int i = fromIndexA, j = fromIndexB, k = 0; k < len; i++, j++, k++) { if (((a[i] == null || b[j] == null) ? (a != b) : !a[i].equalsIgnoreCase(b[j]))) { return false; } } return true; } /** * Compares two maps for equality based on the specified keys. * * @param map1 the first map to compare, must not be null * @param map2 the second map to compare, must not be null * @param keysToCompare the collection of keys to compare, must not be null * @return {@code true} if the values associated with the specified keys in both maps are equal, {@code false} otherwise * @throws IllegalArgumentException if the {@code keysToCompare} is empty */ public static boolean equalsByKeys(final Map map1, final Map map2, final Collection keysToCompare) throws IllegalArgumentException { N.checkArgNotEmpty(keysToCompare, cs.keysToCompare); if (map1 == map2) { return true; } else if ((map1 == null && map2 != null) || (map1 != null && map2 == null)) { return false; } for (K key : keysToCompare) { if (!equals(map1.get(key), map2.get(key))) { return false; } } return true; } /** * Compares the properties of two beans to determine if they are equal. * * @param bean1 the first bean to compare, must not be null * @param bean2 the second bean to compare, must not be null * @param propNamesToCompare the collection of property names to compare, must not be null or empty * @return {@code true} if all the specified properties of the beans are equal, {@code false} otherwise * @throws IllegalArgumentException if the {@code propNamesToCompare} is empty */ public static boolean equalsByProps(final Object bean1, final Object bean2, final Collection propNamesToCompare) throws IllegalArgumentException { N.checkArgNotEmpty(propNamesToCompare, cs.propNamesToCompare); return compareByProps(bean1, bean2, propNamesToCompare) == 0; } /** * Compares the properties of two beans to determine if they are equal by common properties. * * @param bean1 the first bean to compare, must not be null * @param bean2 the second bean to compare, must not be null * @return {@code true} if all the common properties of the beans are equal, {@code false} otherwise * @throws IllegalArgumentException if no common property is found */ public static boolean equalsByCommonProps(@NotNull final Object bean1, @NotNull final Object bean2) throws IllegalArgumentException { checkArgNotNull(bean1); checkArgNotNull(bean2); checkArgument(ClassUtil.isBeanClass(bean1.getClass()), "{} is not a bean class", bean1.getClass()); checkArgument(ClassUtil.isBeanClass(bean2.getClass()), "{} is not a bean class", bean2.getClass()); final List propNamesToCompare = new ArrayList<>(ClassUtil.getPropNameList(bean1.getClass())); propNamesToCompare.retainAll(ClassUtil.getPropNameList(bean2.getClass())); if (isEmpty(propNamesToCompare)) { throw new IllegalArgumentException("No common property found in class: " + bean1.getClass() + " and class: " + bean2.getClass()); } return equalsByProps(bean1, bean2, propNamesToCompare); } /** * Returns the hash code for a boolean value. * * @param value the boolean value * @return the hash code. */ public static int hashCode(final boolean value) { return value ? 1231 : 1237; } /** * Returns the hash code for a char value. * * @param value the char value * @return the hash code */ public static int hashCode(final char value) { return value; } /** * Returns the hash code for a byte value. * * @param value the byte value * @return the hash code */ public static int hashCode(final byte value) { return value; } /** * Returns the hash code for a short value. * * @param value the short value * @return the hash code */ public static int hashCode(final short value) { return value; } /** * Returns the hash code for an int value. * * @param value the int value * @return the hash code */ public static int hashCode(final int value) { return value; } /** * Returns the hash code for a long value. * * @param value the long value * @return the hash code */ public static int hashCode(final long value) { return Long.hashCode(value); } /** * Returns the hash code for a float value. * * @param value the float value * @return the hash code */ public static int hashCode(final float value) { return Float.floatToIntBits(value); } /** * Returns the hash code for a double value. * * @param value the double value * @return the hash code */ public static int hashCode(final double value) { return Double.hashCode(value); } /** * Returns the hash code for an object. If the object is an array, the appropriate {@code Arrays.hashCode} method will be used * * @param obj the object for which the hash code is to be calculated * @return the hash code of the object, or 0 if the object is null */ public static int hashCode(final Object obj) { if (obj == null) { return 0; } if (obj.getClass().isArray()) { return typeOf(obj.getClass()).hashCode(obj); } return obj.hashCode(); } /** * Returns the hash code for an array of booleans. * * @param a the array of booleans * @return the hash code of the array * @see Arrays#hashCode(boolean[]) */ public static int hashCode(final boolean[] a) { return a == null ? 0 : hashCode(a, 0, a.length); } /** * Returns the hash code for a range of elements in a boolean array. * * @param a the array of booleans * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @return the hash code for the specified range of the array * @throws IndexOutOfBoundsException if the indices are out of range */ public static int hashCode(final boolean[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (a == null) { return 0; } int result = 1; for (int i = fromIndex; i < toIndex; i++) { result = 31 * result + (a[i] ? 1231 : 1237); } return result; } /** * Returns the hash code for an array of chars. * * @param a the array of chars * @return the hash code of the array * @see Arrays#hashCode(char[]) */ public static int hashCode(final char[] a) { return a == null ? 0 : hashCode(a, 0, a.length); } /** * Returns the hash code for a range of elements in a char array. * * @param a the array of chars * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @return the hash code for the specified range of the array * @throws IndexOutOfBoundsException if the indices are out of range */ public static int hashCode(final char[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (a == null) { return 0; } int result = 1; for (int i = fromIndex; i < toIndex; i++) { result = 31 * result + a[i]; } return result; } /** * Returns the hash code for an array of bytes. * * @param a the array of bytes * @return the hash code of the array * @see Arrays#hashCode(byte[]) */ public static int hashCode(final byte[] a) { return a == null ? 0 : hashCode(a, 0, a.length); } /** * Returns the hash code for a range of elements in a byte array. * * @param a the array of bytes * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @return the hash code for the specified range of the array * @throws IndexOutOfBoundsException if the indices are out of range */ public static int hashCode(final byte[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (a == null) { return 0; } int result = 1; for (int i = fromIndex; i < toIndex; i++) { result = 31 * result + a[i]; } return result; } /** * Returns the hash code for an array of shorts. * * @param a the array of shorts * @return the hash code of the array * @see Arrays#hashCode(short[]) */ public static int hashCode(final short[] a) { return a == null ? 0 : hashCode(a, 0, a.length); } /** * Returns the hash code for a range of elements in a short array. * * @param a the array of shorts * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @return the hash code for the specified range of the array * @throws IndexOutOfBoundsException if the indices are out of range */ public static int hashCode(final short[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (a == null) { return 0; } int result = 1; for (int i = fromIndex; i < toIndex; i++) { result = 31 * result + a[i]; } return result; } /** * Returns the hash code for an array of ints. * * @param a the array of ints * @return the hash code of the array * @see Arrays#hashCode(int[]) */ public static int hashCode(final int[] a) { return a == null ? 0 : hashCode(a, 0, a.length); } /** * Returns the hash code for a range of elements in an int array. * * @param a the array of ints * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @return the hash code for the specified range of the array * @throws IndexOutOfBoundsException if the indices are out of range */ public static int hashCode(final int[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (a == null) { return 0; } int result = 1; for (int i = fromIndex; i < toIndex; i++) { result = 31 * result + a[i]; } return result; } /** * Returns the hash code for an array of longs. * * @param a the array of longs * @return the hash code of the array * @see Arrays#hashCode(long[]) */ public static int hashCode(final long[] a) { return a == null ? 0 : hashCode(a, 0, a.length); } /** * Returns the hash code for a range of elements in a long array. * * @param a the array of longs * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @return the hash code for the specified range of the array * @throws IndexOutOfBoundsException if the indices are out of range */ public static int hashCode(final long[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (a == null) { return 0; } int result = 1; for (int i = fromIndex; i < toIndex; i++) { result = 31 * result + Long.hashCode(a[i]); } return result; } /** * Returns the hash code for an array of floats. * * @param a the array of floats * @return the hash code of the array * @see Arrays#hashCode(float[]) */ public static int hashCode(final float[] a) { return a == null ? 0 : hashCode(a, 0, a.length); } /** * Returns the hash code for a range of elements in a float array. * * @param a the array of floats * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @return the hash code for the specified range of the array * @throws IndexOutOfBoundsException if the indices are out of range */ public static int hashCode(final float[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (a == null) { return 0; } int result = 1; for (int i = fromIndex; i < toIndex; i++) { result = 31 * result + Float.floatToIntBits(a[i]); } return result; } /** * Returns the hash code for an array of doubles. * * @param a the array of doubles * @return the hash code of the array * @see Arrays#hashCode(double[]) */ public static int hashCode(final double[] a) { return a == null ? 0 : hashCode(a, 0, a.length); } /** * Returns the hash code for a range of elements in a double array. * * @param a the array of doubles * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @return the hash code for the specified range of the array * @throws IndexOutOfBoundsException if the indices are out of range */ public static int hashCode(final double[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (a == null) { return 0; } int result = 1; for (int i = fromIndex; i < toIndex; i++) { result = 31 * result + Double.hashCode(a[i]); } return result; } /** * Returns the hash code for an array of Objects. * * @param a the array of Objects * @return the hash code of the array * @see Arrays#hashCode(Object[]) */ public static int hashCode(final Object[] a) { return a == null ? 0 : hashCode(a, 0, a.length); } /** * Returns the hash code for a range of elements in an Object array. * * @param a the array of Objects * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @return the hash code for the specified range of the array * @throws IndexOutOfBoundsException if the indices are out of range */ public static int hashCode(final Object[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (a == null) { return 0; } int result = 1; for (int i = fromIndex; i < toIndex; i++) { result = 31 * result + (a[i] == null ? 0 : a[i].hashCode()); } return result; } /** * Returns the hash code for the specified object. If the object is an array, the appropriate {@code Arrays.deepHashCode} method will be used. * * @param obj the object for which the hash code is to be calculated * @return the hash code of the object, or 0 if the object is null * @see Arrays#deepHashCode(Object[]) */ public static int deepHashCode(final Object obj) { if (obj == null) { return 0; } final Class cls = obj.getClass(); if (cls.isArray()) { final Integer enumInt = CLASS_TYPE_ENUM.get(cls); if (enumInt == null) { return deepHashCode((Object[]) obj); } switch (enumInt) { case 11: return hashCode((boolean[]) obj); case 12: return hashCode((char[]) obj); case 13: return hashCode((byte[]) obj); case 14: return hashCode((short[]) obj); case 15: return hashCode((int[]) obj); case 16: return hashCode((long[]) obj); case 17: return hashCode((float[]) obj); case 18: return hashCode((double[]) obj); case 19: return hashCode((String[]) obj); default: return deepHashCode((Object[]) obj); } } return obj.hashCode(); } /** * Returns the hash code for an array of Objects. * * @param a the array of Objects * @return the hash code of the array * @see Arrays#deepHashCode(Object[]) */ public static int deepHashCode(final Object[] a) { return a == null ? 0 : deepHashCode(a, 0, a.length); } /** * Returns the hash code for a range of elements in an Object array. * * @param a the array of Objects * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @return the hash code for the specified range of the array * @throws IndexOutOfBoundsException if the indices are out of range * @see Arrays#deepHashCode(Object[]) */ public static int deepHashCode(final Object[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (a == null) { return 0; } int result = 1; for (int i = fromIndex; i < toIndex; i++) { result = 31 * result + (a[i] == null ? 0 : deepHashCode(a[i])); } return result; } /** * Returns a string representation of the specified boolean value. * * @param value the boolean value to be represented as a string * @return the String representation of the boolean value */ public static String toString(final boolean value) { return stringOf(value); } /** * Returns a string representation of the specified char value. * * @param value the char value to be represented as a string * @return the String representation of the char value */ public static String toString(final char value) { return stringOf(value); } /** * Returns a string representation of the specified byte value. * * @param value the byte value to be represented as a string * @return the String representation of the byte value */ public static String toString(final byte value) { return stringOf(value); } /** * Returns a string representation of the specified short value. * * @param value the short value to be represented as a string * @return the String representation of the short value */ public static String toString(final short value) { return stringOf(value); } /** * Returns a string representation of the specified int value. * * @param value the int value to be represented as a string * @return the String representation of the int value */ public static String toString(final int value) { return stringOf(value); } /** * Returns a string representation of the specified long value. * * @param value the long value to be represented as a string * @return the String representation of the long value */ public static String toString(final long value) { return stringOf(value); } /** * Returns a string representation of the specified float value. * * @param value the float value to be represented as a string * @return the String representation of the float value */ public static String toString(final float value) { return stringOf(value); } /** * Returns a string representation of the specified double value. * * @param value the double value to be represented as a string * @return the String representation of the double value */ public static String toString(final double value) { return stringOf(value); } /** * Returns a string representation of the specified object. * * @param obj the object to be represented as a string * @return the String representation of the object. If the object is {@code null}, the string {@code "null"} is returned. */ public static String toString(final Object obj) { if (obj == null) { return Strings.NULL; } else if (obj instanceof CharSequence) { return obj.toString(); } if (obj.getClass().isArray()) { return typeOf(obj.getClass()).toString(obj); } if (obj instanceof final Iterator iter) { // NOSONAR return Strings.join(iter, ", ", "[", "]"); } if (obj instanceof final Iterable iter) { // NOSONAR return Strings.join(iter, ", ", "[", "]"); } final Integer typeIdx = CLASS_TYPE_ENUM.get(obj.getClass()); if (typeIdx == null) { return obj.toString(); } switch (typeIdx) { case 21: return toString(((Boolean) obj).booleanValue()); case 22: return toString(((Character) obj).charValue()); case 23: return toString(((Byte) obj).byteValue()); case 24: return toString(((Short) obj).shortValue()); case 25: return toString(((Integer) obj).intValue()); case 26: return toString(((Long) obj).longValue()); // case 27: // return toString(((Float) obj).floatValue()); // // case 28: // return toString(((Double) obj).doubleValue()); default: return obj.toString(); } } /** * Returns a string representation of the specified object. If the object is {@code null}, the specified default value is returned. * * @param obj the object to be represented as a string * @param defaultIfNull the default value to be returned if the object is null * @return the String representation of the object, or the default value if the object is null */ public static String toString(final Object obj, final String defaultIfNull) { return obj == null ? defaultIfNull : toString(obj); } /** * Returns a string representation of the specified boolean array. * * @param a the boolean array to be represented as a string * @return the String representation of the boolean array * @see Arrays#toString(boolean[]) */ public static String toString(final boolean[] a) { if (a == null) { return Strings.NULL; } else if (a.length == 0) { return Strings.STR_FOR_EMPTY_ARRAY; } return toString(a, 0, a.length); } /** * Returns a string representation of the specified range of elements in a boolean array. * * @param a the boolean array to be represented as a string * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @return the String representation of the specified range of the boolean array * @throws IndexOutOfBoundsException if the indices are out of range */ public static String toString(final boolean[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (a == null) { return Strings.NULL; } else if (a.length == 0) { return Strings.STR_FOR_EMPTY_ARRAY; } // final StringBuilder sb = Objectory.createStringBuilder(calculateBufferSize(toIndex - fromIndex, 7)); // // try { // toString(sb, a, fromIndex, toIndex); // // return sb.toString(); // } finally { // Objectory.recycle(sb); // } return Strings.join(a, 0, len(a), Strings.ELEMENT_SEPARATOR, WD.BRACKET_L, WD.BRACKET_R); } /** * * @param sb * @param a */ static void toString(final StringBuilder sb, final boolean[] a) { if (a == null) { sb.append(Strings.NULL); } else if (a.length == 0) { sb.append(Strings.STR_FOR_EMPTY_ARRAY); } else { toString(sb, a, 0, a.length); } } /** * * @param sb * @param a * @param fromIndex * @param toIndex * @throws IndexOutOfBoundsException */ static void toString(final StringBuilder sb, final boolean[] a, final int fromIndex, final int toIndex) { sb.append(WD._BRACKET_L); for (int i = fromIndex; i < toIndex; i++) { if (i > fromIndex) { sb.append(Strings.ELEMENT_SEPARATOR); } sb.append(a[i]); } sb.append(WD._BRACKET_R); } /** * Returns a string representation of the specified char array. * * @param a the char array to be represented as a string * @return the String representation of the char array * @see Arrays#toString(char[]) */ public static String toString(final char[] a) { if (a == null) { return Strings.NULL; } else if (a.length == 0) { return Strings.STR_FOR_EMPTY_ARRAY; } return toString(a, 0, a.length); } /** * Returns a string representation of the specified range of elements in a char array. * * @param a the char array to be represented as a string * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @return the String representation of the specified range of the char array * @throws IndexOutOfBoundsException if the indices are out of range */ public static String toString(final char[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (a == null) { return Strings.NULL; } else if (a.length == 0) { return Strings.STR_FOR_EMPTY_ARRAY; } // final StringBuilder sb = Objectory.createStringBuilder(calculateBufferSize(toIndex - fromIndex, 3)); // // try { // toString(sb, a, fromIndex, toIndex); // // return sb.toString(); // } finally { // Objectory.recycle(sb); // } return Strings.join(a, 0, len(a), Strings.ELEMENT_SEPARATOR, WD.BRACKET_L, WD.BRACKET_R); } /** * * @param sb * @param a */ static void toString(final StringBuilder sb, final char[] a) { if (a == null) { sb.append(Strings.NULL); } else if (a.length == 0) { sb.append(Strings.STR_FOR_EMPTY_ARRAY); } else { toString(sb, a, 0, a.length); } } /** * * @param sb * @param a * @param fromIndex * @param toIndex */ static void toString(final StringBuilder sb, final char[] a, final int fromIndex, final int toIndex) { sb.append(WD._BRACKET_L); for (int i = fromIndex; i < toIndex; i++) { if (i > fromIndex) { sb.append(Strings.ELEMENT_SEPARATOR); } sb.append(a[i]); } sb.append(WD._BRACKET_R); } /** * Returns a string representation of the specified byte array. * * @param a the byte array to be represented as a string * @return the String representation of the byte array * @see Arrays#toString(byte[]) */ public static String toString(final byte[] a) { if (a == null) { return Strings.NULL; } else if (a.length == 0) { return Strings.STR_FOR_EMPTY_ARRAY; } return toString(a, 0, a.length); } /** * Returns a string representation of the specified range of elements in a byte array. * * @param a the byte array to be represented as a string * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @return the String representation of the specified range of the byte array * @throws IndexOutOfBoundsException if the indices are out of range */ public static String toString(final byte[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (a == null) { return Strings.NULL; } else if (a.length == 0) { return Strings.STR_FOR_EMPTY_ARRAY; } // final StringBuilder sb = Objectory.createStringBuilder(calculateBufferSize(toIndex - fromIndex, 6)); // // try { // toString(sb, a, fromIndex, toIndex); // // return sb.toString(); // } finally { // Objectory.recycle(sb); // } return Strings.join(a, 0, len(a), Strings.ELEMENT_SEPARATOR, WD.BRACKET_L, WD.BRACKET_R); } /** * * @param sb * @param a */ static void toString(final StringBuilder sb, final byte[] a) { if (a == null) { sb.append(Strings.NULL); } else if (a.length == 0) { sb.append(Strings.STR_FOR_EMPTY_ARRAY); } else { toString(sb, a, 0, a.length); } } /** * * @param sb * @param a * @param fromIndex * @param toIndex */ static void toString(final StringBuilder sb, final byte[] a, final int fromIndex, final int toIndex) { sb.append(WD._BRACKET_L); for (int i = fromIndex; i < toIndex; i++) { if (i > fromIndex) { sb.append(Strings.ELEMENT_SEPARATOR); } sb.append(a[i]); } sb.append(WD._BRACKET_R); } /** * Returns a string representation of the specified short array. * * @param a the short array to be represented as a string * @return the String representation of the short array * @see Arrays#toString(short[]) */ public static String toString(final short[] a) { if (a == null) { return Strings.NULL; } else if (a.length == 0) { return Strings.STR_FOR_EMPTY_ARRAY; } return toString(a, 0, a.length); } /** * Returns a string representation of the specified range of elements in a short array. * * @param a the short array to be represented as a string * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @return the String representation of the specified range of the short array * @throws IndexOutOfBoundsException if the indices are out of range */ public static String toString(final short[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (a == null) { return Strings.NULL; } else if (a.length == 0) { return Strings.STR_FOR_EMPTY_ARRAY; } // final StringBuilder sb = Objectory.createStringBuilder(calculateBufferSize(toIndex - fromIndex, 7)); // // try { // toString(sb, a, fromIndex, toIndex); // // return sb.toString(); // } finally { // Objectory.recycle(sb); // } return Strings.join(a, 0, len(a), Strings.ELEMENT_SEPARATOR, WD.BRACKET_L, WD.BRACKET_R); } /** * * @param sb * @param a */ static void toString(final StringBuilder sb, final short[] a) { if (a == null) { sb.append(Strings.NULL); } else if (a.length == 0) { sb.append(Strings.STR_FOR_EMPTY_ARRAY); } else { toString(sb, a, 0, a.length); } } /** * * @param sb * @param a * @param fromIndex * @param toIndex */ static void toString(final StringBuilder sb, final short[] a, final int fromIndex, final int toIndex) { sb.append(WD._BRACKET_L); for (int i = fromIndex; i < toIndex; i++) { if (i > fromIndex) { sb.append(Strings.ELEMENT_SEPARATOR); } sb.append(a[i]); } sb.append(WD._BRACKET_R); } /** * Returns a string representation of the specified int array. * * @param a the int array to be represented as a string * @return the String representation of the int array * @see Arrays#toString(int[]) */ public static String toString(final int[] a) { if (a == null) { return Strings.NULL; } else if (a.length == 0) { return Strings.STR_FOR_EMPTY_ARRAY; } return toString(a, 0, a.length); } /** * Returns a string representation of the specified range of elements in an int array. * * @param a the int array to be represented as a string * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @return the String representation of the specified range of the int array * @throws IndexOutOfBoundsException if the indices are out of range */ public static String toString(final int[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (a == null) { return Strings.NULL; } else if (a.length == 0) { return Strings.STR_FOR_EMPTY_ARRAY; } // final StringBuilder sb = Objectory.createStringBuilder(calculateBufferSize(toIndex - fromIndex, 8)); // // try { // toString(sb, a, fromIndex, toIndex); // // return sb.toString(); // } finally { // Objectory.recycle(sb); // } return Strings.join(a, 0, len(a), Strings.ELEMENT_SEPARATOR, WD.BRACKET_L, WD.BRACKET_R); } /** * * @param sb * @param a */ static void toString(final StringBuilder sb, final int[] a) { if (a == null) { sb.append(Strings.NULL); } else if (a.length == 0) { sb.append(Strings.STR_FOR_EMPTY_ARRAY); } else { toString(sb, a, 0, a.length); } } /** * * @param sb * @param a * @param fromIndex * @param toIndex */ static void toString(final StringBuilder sb, final int[] a, final int fromIndex, final int toIndex) { sb.append(WD._BRACKET_L); for (int i = fromIndex; i < toIndex; i++) { if (i > fromIndex) { sb.append(Strings.ELEMENT_SEPARATOR); } sb.append(a[i]); } sb.append(WD._BRACKET_R); } /** * Returns a string representation of the specified long array. * * @param a the long array to be represented as a string * @return the String representation of the long array * @see Arrays#toString(long[]) */ public static String toString(final long[] a) { if (a == null) { return Strings.NULL; } else if (a.length == 0) { return Strings.STR_FOR_EMPTY_ARRAY; } return toString(a, 0, a.length); } /** * Returns a string representation of the specified range of elements in a long array. * * @param a the long array to be represented as a string * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @return the String representation of the specified range of the long array * @throws IndexOutOfBoundsException if the indices are out of range */ public static String toString(final long[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (a == null) { return Strings.NULL; } else if (a.length == 0) { return Strings.STR_FOR_EMPTY_ARRAY; } // final StringBuilder sb = Objectory.createStringBuilder(calculateBufferSize(toIndex - fromIndex, 8)); // // try { // toString(sb, a, fromIndex, toIndex); // // return sb.toString(); // } finally { // Objectory.recycle(sb); // } return Strings.join(a, 0, len(a), Strings.ELEMENT_SEPARATOR, WD.BRACKET_L, WD.BRACKET_R); } /** * * @param sb * @param a */ static void toString(final StringBuilder sb, final long[] a) { if (a == null) { sb.append(Strings.NULL); } else if (a.length == 0) { sb.append(Strings.STR_FOR_EMPTY_ARRAY); } else { toString(sb, a, 0, a.length); } } /** * * @param sb * @param a * @param fromIndex * @param toIndex */ static void toString(final StringBuilder sb, final long[] a, final int fromIndex, final int toIndex) { sb.append(WD._BRACKET_L); for (int i = fromIndex; i < toIndex; i++) { if (i > fromIndex) { sb.append(Strings.ELEMENT_SEPARATOR); } sb.append(a[i]); } sb.append(WD._BRACKET_R); } /** * Returns a string representation of the specified float array. * * @param a the float array to be represented as a string * @return the String representation of the float array * @see Arrays#toString(float[]) */ public static String toString(final float[] a) { if (a == null) { return Strings.NULL; } else if (a.length == 0) { return Strings.STR_FOR_EMPTY_ARRAY; } return toString(a, 0, a.length); } /** * Returns a string representation of the specified range of elements in a float array. * * @param a the float array to be represented as a string * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @return the String representation of the specified range of the float array * @throws IndexOutOfBoundsException if the indices are out of range */ public static String toString(final float[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (a == null) { return Strings.NULL; } else if (a.length == 0) { return Strings.STR_FOR_EMPTY_ARRAY; } // final StringBuilder sb = Objectory.createStringBuilder(calculateBufferSize(toIndex - fromIndex, 8)); // // try { // toString(sb, a, fromIndex, toIndex); // // return sb.toString(); // } finally { // Objectory.recycle(sb); // } return Strings.join(a, 0, len(a), Strings.ELEMENT_SEPARATOR, WD.BRACKET_L, WD.BRACKET_R); } /** * * @param sb * @param a */ static void toString(final StringBuilder sb, final float[] a) { if (a == null) { sb.append(Strings.NULL); } else if (a.length == 0) { sb.append(Strings.STR_FOR_EMPTY_ARRAY); } else { toString(sb, a, 0, a.length); } } /** * * @param sb * @param a * @param fromIndex * @param toIndex */ static void toString(final StringBuilder sb, final float[] a, final int fromIndex, final int toIndex) { sb.append(WD._BRACKET_L); for (int i = fromIndex; i < toIndex; i++) { if (i > fromIndex) { sb.append(Strings.ELEMENT_SEPARATOR); } sb.append(a[i]); } sb.append(WD._BRACKET_R); } /** * Returns a string representation of the specified double array. * * @param a the double array to be represented as a string * @return the String representation of the double array * @see Arrays#toString(double[]) */ public static String toString(final double[] a) { if (a == null) { return Strings.NULL; } else if (a.length == 0) { return Strings.STR_FOR_EMPTY_ARRAY; } return toString(a, 0, a.length); } /** * Returns a string representation of the specified range of elements in a double array. * * @param a the double array to be represented as a string * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @return the String representation of the specified range of the double array * @throws IndexOutOfBoundsException if the indices are out of range */ public static String toString(final double[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (a == null) { return Strings.NULL; } else if (a.length == 0) { return Strings.STR_FOR_EMPTY_ARRAY; } // final StringBuilder sb = Objectory.createStringBuilder(calculateBufferSize(toIndex - fromIndex, 8)); // // try { // toString(sb, a, fromIndex, toIndex); // // return sb.toString(); // } finally { // Objectory.recycle(sb); // } return Strings.join(a, 0, len(a), Strings.ELEMENT_SEPARATOR, WD.BRACKET_L, WD.BRACKET_R); } /** * * @param sb * @param a */ static void toString(final StringBuilder sb, final double[] a) { if (a == null) { sb.append(Strings.NULL); } else if (a.length == 0) { sb.append(Strings.STR_FOR_EMPTY_ARRAY); } else { toString(sb, a, 0, a.length); } } /** * * @param sb * @param a * @param fromIndex * @param toIndex */ static void toString(final StringBuilder sb, final double[] a, final int fromIndex, final int toIndex) { sb.append(WD._BRACKET_L); for (int i = fromIndex; i < toIndex; i++) { if (i > fromIndex) { sb.append(Strings.ELEMENT_SEPARATOR); } sb.append(a[i]); } sb.append(WD._BRACKET_R); } /** * Returns a string representation of the specified Object array. * * @param a the Object array to be represented as a string * @return the String representation of the Object array * @see Arrays#toString(Object[]) */ public static String toString(final Object[] a) { if (a == null) { return Strings.NULL; } else if (a.length == 0) { return Strings.STR_FOR_EMPTY_ARRAY; } return toString(a, 0, a.length); } /** * Returns a string representation of the specified range of elements in an Object array. * * @param a the Object array to be represented as a string * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @return the String representation of the specified range of the Object array * @throws IndexOutOfBoundsException if the indices are out of range */ public static String toString(final Object[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (a == null) { return Strings.NULL; } else if (a.length == 0) { return Strings.STR_FOR_EMPTY_ARRAY; } // final StringBuilder sb = Objectory.createStringBuilder(calculateBufferSize(toIndex - fromIndex, 16)); // // try { // toString(sb, a, fromIndex, toIndex); // // return sb.toString(); // } finally { // Objectory.recycle(sb); // } return Strings.join(a, Strings.ELEMENT_SEPARATOR, WD.BRACKET_L, WD.BRACKET_R); } /** * * @param sb * @param a */ static void toString(final StringBuilder sb, final Object[] a) { if (a == null) { sb.append(Strings.NULL); } else if (a.length == 0) { sb.append(Strings.STR_FOR_EMPTY_ARRAY); } else { toString(sb, a, 0, a.length); } } /** * * @param sb * @param a * @param fromIndex * @param toIndex */ static void toString(final StringBuilder sb, final Object[] a, final int fromIndex, final int toIndex) { sb.append(WD._BRACKET_L); for (int i = fromIndex; i < toIndex; i++) { if (i > fromIndex) { sb.append(Strings.ELEMENT_SEPARATOR); } sb.append(toString(a[i])); } sb.append(WD._BRACKET_R); } /** * Returns a string representation of the "deep contents" of the specified object. If the object is an array, the appropriate {@code Arrays.toString(array)} method will be used. * This method recursively converts the object and its nested objects to a string. * * @param obj the object to be represented as a string * @return the string representation of the object */ public static String deepToString(final Object obj) { if (obj == null) { return Strings.NULL; } final Class cls = obj.getClass(); if (cls.isArray()) { final Integer enumInt = CLASS_TYPE_ENUM.get(cls); if (enumInt == null) { return deepToString((Object[]) obj); } switch (enumInt) { case 11: return toString((boolean[]) obj); case 12: return toString((char[]) obj); case 13: return toString((byte[]) obj); case 14: return toString((short[]) obj); case 15: return toString((int[]) obj); case 16: return toString((long[]) obj); case 17: return toString((float[]) obj); case 18: return toString((double[]) obj); case 19: return toString((String[]) obj); default: return deepToString((Object[]) obj); } } return obj.toString(); } /** * Returns a string representation of the "deep contents" of the specified array. If the object is {@code null}, the specified default value is returned. * * @param a the object array to be represented as a string * @return the String representation of the object, or the default value if the object is null * @see Arrays#deepToString(Object[]) */ public static String deepToString(final Object[] a) { if (a == null) { return Strings.NULL; } else if (a.length == 0) { return Strings.STR_FOR_EMPTY_ARRAY; } return deepToString(a, 0, a.length); } /** * Returns a string representation of the "deep contents" of the specified range of elements in an Object array. * This method recursively converts the object and its nested objects to a string. * * @param a the Object array to be represented as a string * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @return the String representation of the specified range of the Object array * @throws IndexOutOfBoundsException if the indices are out of range * @see Arrays#deepToString(Object[]) */ public static String deepToString(final Object[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR final StringBuilder sb = Objectory.createStringBuilder(calculateBufferSize(toIndex - fromIndex, 32)); final Set set = newSetFromMap(newIdentityHashMap(len(a))); try { deepToString(sb, a, fromIndex, toIndex, set); return sb.toString(); } finally { Objectory.recycle(sb); } } /** * Deep to string. * * @param sb * @param a * @param processedElements */ static void deepToString(final StringBuilder sb, final Object[] a, final Set processedElements) { deepToString(sb, a, 0, a.length, processedElements); } /** * Deep to string. * * @param sb * @param a * @param fromIndex * @param toIndex * @param processedElements */ static void deepToString(final StringBuilder sb, final Object[] a, final int fromIndex, final int toIndex, final Set processedElements) { processedElements.add(a); sb.append(WD._BRACKET_L); Object element = null; Class eClass = null; for (int i = fromIndex; i < toIndex; i++) { element = a[i]; if (i > fromIndex) { sb.append(Strings.ELEMENT_SEPARATOR); } if (element == null) { sb.append(Strings.NULL_CHAR_ARRAY); continue; } eClass = element.getClass(); if (eClass.isArray()) { final Integer enumInt = CLASS_TYPE_ENUM.get(eClass); final int num = enumInt == null ? 0 : enumInt; switch (num) { case 11: toString(sb, (boolean[]) element); break; case 12: toString(sb, (char[]) element); break; case 13: toString(sb, (byte[]) element); break; case 14: toString(sb, (short[]) element); break; case 15: toString(sb, (int[]) element); break; case 16: toString(sb, (long[]) element); break; case 17: toString(sb, (float[]) element); break; case 18: toString(sb, (double[]) element); break; case 19: toString(sb, (String[]) element); break; default: if (processedElements.contains(element)) { sb.append("[...]"); } else { deepToString(sb, (Object[]) element, processedElements); } } } else { // element is non-null and not an array //noinspection UnnecessaryToStringCall sb.append(element.toString()); } } sb.append(WD._BRACKET_R); processedElements.remove(a); } /** * Returns a string representation of the "deep contents" of the specified array. If the object is {@code null}, the specified default value is returned. * * @param a the Object array to be represented as a string * @param defaultIfNull the default value to be returned if the object is null * @return the String representation of the object, or the default value if the object is null * @see Arrays#deepToString(Object[]) */ public static String deepToString(final Object[] a, final String defaultIfNull) { return a == null ? defaultIfNull : deepToString(a); } /** * Reverses the order of the elements in the specified boolean array. * The reversing is performed in-place, meaning the original array is modified. * * @param a the boolean array to be reversed */ public static void reverse(final boolean[] a) { if (isEmpty(a)) { return; } reverse(a, 0, a.length); } /** * Reverses the order of the elements in the specified range of the specified boolean array. * The reversing is performed in-place, meaning the original array is modified. * * @param a the boolean array to be reversed * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @throws IndexOutOfBoundsException if the indices are out of range */ public static void reverse(final boolean[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (toIndex - fromIndex <= 1) { return; } boolean tmp = false; for (int i = fromIndex, j = toIndex - 1; i < j; i++, j--) { tmp = a[i]; a[i] = a[j]; a[j] = tmp; } } /** * Reverses the order of the elements in the specified char array. * The reversing is performed in-place, meaning the original array is modified. * * @param a the char array to be reversed */ public static void reverse(final char[] a) { if (isEmpty(a)) { return; } reverse(a, 0, a.length); } /** * Reverses the order of the elements in the specified range of the specified char array. * The reversing is performed in-place, meaning the original array is modified. * * @param a the char array to be reversed * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @throws IndexOutOfBoundsException if the indices are out of range */ public static void reverse(final char[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (toIndex - fromIndex <= 1) { return; } char tmp = 0; for (int i = fromIndex, j = toIndex - 1; i < j; i++, j--) { tmp = a[i]; a[i] = a[j]; a[j] = tmp; } } /** * Reverses the order of the elements in the specified byte array. * The reversing is performed in-place, meaning the original array is modified. * * @param a the byte array to be reversed */ public static void reverse(final byte[] a) { if (isEmpty(a)) { return; } reverse(a, 0, a.length); } /** * Reverses the order of the elements in the specified range of the specified byte array. * The reversing is performed in-place, meaning the original array is modified. * * @param a the byte array to be reversed * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @throws IndexOutOfBoundsException if the indices are out of range */ public static void reverse(final byte[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (toIndex - fromIndex <= 1) { return; } byte tmp = 0; for (int i = fromIndex, j = toIndex - 1; i < j; i++, j--) { tmp = a[i]; a[i] = a[j]; a[j] = tmp; } } /** * Reverses the order of the elements in the specified short array. * The reversing is performed in-place, meaning the original array is modified. * * @param a the short array to be reversed */ public static void reverse(final short[] a) { if (isEmpty(a)) { return; } reverse(a, 0, a.length); } /** * Reverses the order of the elements in the specified range of the specified short array. * The reversing is performed in-place, meaning the original array is modified. * * @param a the short array to be reversed * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @throws IndexOutOfBoundsException if the indices are out of range */ public static void reverse(final short[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (toIndex - fromIndex <= 1) { return; } short tmp = 0; for (int i = fromIndex, j = toIndex - 1; i < j; i++, j--) { tmp = a[i]; a[i] = a[j]; a[j] = tmp; } } /** * Reverses the order of the elements in the specified int array. * The reversing is performed in-place, meaning the original array is modified. * * @param a the int array to be reversed */ public static void reverse(final int[] a) { if (isEmpty(a)) { return; } reverse(a, 0, a.length); } /** * Reverses the order of the elements in the specified range of the specified int array. * The reversing is performed in-place, meaning the original array is modified. * * @param a the int array to be reversed * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @throws IndexOutOfBoundsException if the indices are out of range */ public static void reverse(final int[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (toIndex - fromIndex <= 1) { return; } int tmp = 0; for (int i = fromIndex, j = toIndex - 1; i < j; i++, j--) { tmp = a[i]; a[i] = a[j]; a[j] = tmp; } } /** * Reverses the order of the elements in the specified long array. * The reversing is performed in-place, meaning the original array is modified. * * @param a the long array to be reversed */ public static void reverse(final long[] a) { if (isEmpty(a)) { return; } reverse(a, 0, a.length); } /** * Reverses the order of the elements in the specified range of the specified long array. * The reversing is performed in-place, meaning the original array is modified. * * @param a the long array to be reversed * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @throws IndexOutOfBoundsException if the indices are out of range */ public static void reverse(final long[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (toIndex - fromIndex <= 1) { return; } long tmp = 0L; //NOSONAR for (int i = fromIndex, j = toIndex - 1; i < j; i++, j--) { tmp = a[i]; a[i] = a[j]; a[j] = tmp; } } /** * Reverses the order of the elements in the specified float array. * The reversing is performed in-place, meaning the original array is modified. * * @param a the float array to be reversed */ public static void reverse(final float[] a) { if (isEmpty(a)) { return; } reverse(a, 0, a.length); } /** * Reverses the order of the elements in the specified range of the specified float array. * The reversing is performed in-place, meaning the original array is modified. * * @param a the float array to be reversed * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @throws IndexOutOfBoundsException if the indices are out of range */ public static void reverse(final float[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (toIndex - fromIndex <= 1) { return; } float tmp = 0f; //NOSONAR for (int i = fromIndex, j = toIndex - 1; i < j; i++, j--) { tmp = a[i]; a[i] = a[j]; a[j] = tmp; } } /** * Reverses the order of the elements in the specified double array. * The reversing is performed in-place, meaning the original array is modified. * * @param a the double array to be reversed */ public static void reverse(final double[] a) { if (isEmpty(a)) { return; } reverse(a, 0, a.length); } /** * Reverses the order of the elements in the specified range of the specified double array. * The reversing is performed in-place, meaning the original array is modified. * * @param a the double array to be reversed * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @throws IndexOutOfBoundsException if the indices are out of range */ public static void reverse(final double[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (toIndex - fromIndex <= 1) { return; } double tmp = 0d; //NOSONAR for (int i = fromIndex, j = toIndex - 1; i < j; i++, j--) { tmp = a[i]; a[i] = a[j]; a[j] = tmp; } } /** * Reverses the order of the elements in the specified object array. * The reversing is performed in-place, meaning the original array is modified. * * @param a the object array to be reversed */ public static void reverse(final Object[] a) { if (isEmpty(a)) { return; } reverse(a, 0, a.length); } /** * Reverses the order of the elements in the specified range of the specified object array. * The reversing is performed in-place, meaning the original array is modified. * * @param a the object array to be reversed * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @throws IndexOutOfBoundsException if the indices are out of range */ public static void reverse(final Object[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (toIndex - fromIndex <= 1) { return; } Object tmp = null; for (int i = fromIndex, j = toIndex - 1; i < j; i++, j--) { tmp = a[i]; a[i] = a[j]; a[j] = tmp; } } /** * Reverses the order of the elements in the specified list. * The reversing is performed in-place, meaning the original list is modified. * * @param list the list to be reversed * @see #reverse(Collection) * @see #reverseToList(Collection) * @see Iterables#reverse(List) */ public static void reverse(final List list) { if (isEmpty(list)) { return; } reverse(list, 0, list.size()); } /** * Reverses the order of the elements in the specified range of the specified list. * The reversing is performed in-place, meaning the original list is modified. * * @param list the list to be reversed * @param fromIndex the starting index (inclusive) * @param toIndex the ending index (exclusive) * @throws IndexOutOfBoundsException if the indices are out of range * @see #reverse(Collection) * @see #reverseToList(Collection) * @see Iterables#reverse(List) */ public static void reverse(final List list, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, size(list)); if (toIndex - fromIndex <= 1) { return; } final List l = (List) list; if (toIndex - fromIndex < REVERSE_THRESHOLD || list instanceof RandomAccess) { for (int i = fromIndex, j = toIndex - 1; i < j; i++, j--) { l.set(i, l.set(j, l.get(i))); } } else { final ListIterator fwd = l.listIterator(fromIndex); final ListIterator rev = l.listIterator(toIndex); for (int i = 0, mid = (toIndex - fromIndex) / 2; i < mid; i++) { final Object tmp = fwd.next(); fwd.set(rev.previous()); rev.set(tmp); } } } // replaced by SequencedCollection in JDK 21? /** * Reverses the order of the elements in the specified collection that has a well-defined encounter order. * The reversing is performed in-place, meaning the original collection is modified. * * @param c the collection to be reversed. It should be a collection that has a well-defined encounter order. * @see #reverse(List) * @see #reverseToList(Collection) * @see Iterables#reverse(List) */ @Beta @SuppressWarnings("rawtypes") public static void reverse(final Collection c) { if (isEmpty(c) || c.size() <= 1) { return; } if (c instanceof List) { reverse((List) c); } else { final Object[] tmp = c.toArray(); reverse(tmp); c.clear(); c.addAll((List) Arrays.asList(tmp)); } } // replaced by SequencedCollection in JDK 21? /** * Returns a new list with the elements from the specified collection in reverse order. * The specified collection doesn't need to have a well-defined encounter order and won't be modified. * * @param the type of elements in the collection * @param c the collection whose elements will be added to the returned list in reverse order. * @return a new list with the elements from the specified collection in reverse order. * @see #reverse(List) * @see #reverse(Collection) * @see Iterables#reverse(List) */ @Beta public static List reverseToList(final Collection c) { if (isEmpty(c)) { return new ArrayList<>(); } final List result = new ArrayList<>(c); reverse(result); return result; } /** * Rotates the elements of the specified boolean array by the specified distance. * The rotation is performed in-place, meaning the original array is modified. * * @param a the boolean array to be rotated * @param distance the distance to rotate the array. Positive values rotate the array to the right, * and negative values rotate the array to the left. */ public static void rotate(final boolean[] a, int distance) { if (a == null || a.length <= 1 || distance % a.length == 0) { return; } final int len = a.length; distance = distance % len; if (distance < 0) { distance += len; } if (distance == 0) { return; } for (int i = 0, count = 0; count < len; i++) { final boolean tmp = a[i]; int curr = i; int next = curr < distance ? curr - distance + len : curr - distance; while (next != i) { a[curr] = a[next]; curr = next; next = curr < distance ? curr - distance + len : curr - distance; count++; } a[curr] = tmp; count++; } } /** * Rotates the elements of the specified char array by the specified distance. * The rotation is performed in-place, meaning the original array is modified. * * @param a the char array to be rotated * @param distance the distance to rotate the array. Positive values rotate the array to the right, * and negative values rotate the array to the left. */ public static void rotate(final char[] a, int distance) { if (a == null || a.length <= 1 || distance % a.length == 0) { return; } final int len = a.length; distance = distance % len; if (distance < 0) { distance += len; } if (distance == 0) { return; } for (int i = 0, count = 0; count < len; i++) { final char tmp = a[i]; int curr = i; int next = curr < distance ? curr - distance + len : curr - distance; while (next != i) { a[curr] = a[next]; curr = next; next = curr < distance ? curr - distance + len : curr - distance; count++; } a[curr] = tmp; count++; } } /** * Rotates the elements of the specified byte array by the specified distance. * The rotation is performed in-place, meaning the original array is modified. * * @param a the byte array to be rotated * @param distance the distance to rotate the array. Positive values rotate the array to the right, * and negative values rotate the array to the left. */ public static void rotate(final byte[] a, int distance) { if (a == null || a.length <= 1 || distance % a.length == 0) { return; } final int len = a.length; distance = distance % len; if (distance < 0) { distance += len; } if (distance == 0) { return; } for (int i = 0, count = 0; count < len; i++) { final byte tmp = a[i]; int curr = i; int next = curr < distance ? curr - distance + len : curr - distance; while (next != i) { a[curr] = a[next]; curr = next; next = curr < distance ? curr - distance + len : curr - distance; count++; } a[curr] = tmp; count++; } } /** * Rotates the elements of the specified short array by the specified distance. * The rotation is performed in-place, meaning the original array is modified. * * @param a the short array to be rotated * @param distance the distance to rotate the array. Positive values rotate the array to the right, * and negative values rotate the array to the left. */ public static void rotate(final short[] a, int distance) { if (a == null || a.length <= 1 || distance % a.length == 0) { return; } final int len = a.length; distance = distance % len; if (distance < 0) { distance += len; } if (distance == 0) { return; } for (int i = 0, count = 0; count < len; i++) { final short tmp = a[i]; int curr = i; int next = curr < distance ? curr - distance + len : curr - distance; while (next != i) { a[curr] = a[next]; curr = next; next = curr < distance ? curr - distance + len : curr - distance; count++; } a[curr] = tmp; count++; } } /** * Rotates the elements of the specified int array by the specified distance. * The rotation is performed in-place, meaning the original array is modified. * * @param a the int array to be rotated * @param distance the distance to rotate the array. Positive values rotate the array to the right, * and negative values rotate the array to the left. */ public static void rotate(final int[] a, int distance) { if (a == null || a.length <= 1 || distance % a.length == 0) { return; } final int len = a.length; distance = distance % len; if (distance < 0) { distance += len; } if (distance == 0) { return; } for (int i = 0, count = 0; count < len; i++) { final int tmp = a[i]; int curr = i; int next = curr < distance ? curr - distance + len : curr - distance; while (next != i) { a[curr] = a[next]; curr = next; next = curr < distance ? curr - distance + len : curr - distance; count++; } a[curr] = tmp; count++; } } /** * Rotates the elements of the specified long array by the specified distance. * The rotation is performed in-place, meaning the original array is modified. * * @param a the long array to be rotated * @param distance the distance to rotate the array. Positive values rotate the array to the right, * and negative values rotate the array to the left. */ public static void rotate(final long[] a, int distance) { if (a == null || a.length <= 1 || distance % a.length == 0) { return; } final int len = a.length; distance = distance % len; if (distance < 0) { distance += len; } if (distance == 0) { return; } for (int i = 0, count = 0; count < len; i++) { final long tmp = a[i]; int curr = i; int next = curr < distance ? curr - distance + len : curr - distance; while (next != i) { a[curr] = a[next]; curr = next; next = curr < distance ? curr - distance + len : curr - distance; count++; } a[curr] = tmp; count++; } } /** * Rotates the elements of the specified float array by the specified distance. * The rotation is performed in-place, meaning the original array is modified. * * @param a the float array to be rotated * @param distance the distance to rotate the array. Positive values rotate the array to the right, * and negative values rotate the array to the left. */ public static void rotate(final float[] a, int distance) { if (a == null || a.length <= 1 || distance % a.length == 0) { return; } final int len = a.length; distance = distance % len; if (distance < 0) { distance += len; } if (distance == 0) { return; } for (int i = 0, count = 0; count < len; i++) { final float tmp = a[i]; int curr = i; int next = curr < distance ? curr - distance + len : curr - distance; while (next != i) { a[curr] = a[next]; curr = next; next = curr < distance ? curr - distance + len : curr - distance; count++; } a[curr] = tmp; count++; } } /** * Rotates the elements of the specified double array by the specified distance. * The rotation is performed in-place, meaning the original array is modified. * * @param a the double array to be rotated * @param distance the distance to rotate the array. Positive values rotate the array to the right, * and negative values rotate the array to the left. */ public static void rotate(final double[] a, int distance) { if (a == null || a.length <= 1 || distance % a.length == 0) { return; } final int len = a.length; distance = distance % len; if (distance < 0) { distance += len; } if (distance == 0) { return; } for (int i = 0, count = 0; count < len; i++) { final double tmp = a[i]; int curr = i; int next = curr < distance ? curr - distance + len : curr - distance; while (next != i) { a[curr] = a[next]; curr = next; next = curr < distance ? curr - distance + len : curr - distance; count++; } a[curr] = tmp; count++; } } /** * Rotates the elements of the specified Object array by the specified distance. * The rotation is performed in-place, meaning the original array is modified. * * @param a the Object array to be rotated * @param distance the distance to rotate the array. Positive values rotate the array to the right, * and negative values rotate the array to the left. */ public static void rotate(final Object[] a, int distance) { if (a == null || a.length <= 1 || distance % a.length == 0) { return; } final int len = a.length; distance = distance % len; if (distance < 0) { distance += len; } if (distance == 0) { return; } for (int i = 0, count = 0; count < len; i++) { final Object tmp = a[i]; int curr = i; int next = curr < distance ? curr - distance + len : curr - distance; while (next != i) { a[curr] = a[next]; curr = next; next = curr < distance ? curr - distance + len : curr - distance; count++; } a[curr] = tmp; count++; } } /** * Rotates the elements of the specified list by the specified distance. * The rotation is performed in-place, meaning the original list is modified. * * @param list the list to be rotated * @param distance the distance to rotate the array. Positive values rotate the array to the right, * and negative values rotate the array to the left. * @see java.util.Collections#rotate(List, int) */ public static void rotate(final List list, final int distance) { if (list == null || list.size() <= 1 || distance % list.size() == 0) { return; } Collections.rotate(list, distance); } /** * Rotates the elements of the specified collection that has a well-defined encounter order by the specified distance. * The rotation is performed in-place, meaning the original collection is modified. * * @param c the collection to be rotated. It should be a collection that has a well-defined encounter order. * @param distance the distance to rotate the array. Positive values rotate the array to the right, * and negative values rotate the array to the left. * @see #rotate(List, int) * @see java.util.Collections#rotate(List, int) */ @Beta @SuppressWarnings("rawtypes") public static void rotate(final Collection c, final int distance) { if (isEmpty(c) || c.size() < 2) { return; } if (c instanceof List) { rotate((List) c, distance); } else { final Object[] tmp = c.toArray(); rotate(tmp, distance); c.clear(); c.addAll((List) Arrays.asList(tmp)); } } /** * Shuffles the elements of the specified boolean array. * The shuffling is performed in-place, meaning the original array is modified. * * @param a the boolean array to be shuffled */ public static void shuffle(final boolean[] a) { shuffle(a, RAND); } /** * Shuffles the elements of the specified boolean array using the specified random number generator. * The shuffling is performed in-place, meaning the original array is modified. * * @param a the boolean array to be shuffled * @param rnd the random number generator to use */ public static void shuffle(final boolean[] a, final Random rnd) { if (isEmpty(a) || a.length == 1) { return; } for (int i = a.length; i > 1; i--) { swap(a, i - 1, rnd.nextInt(i)); } } /** * Shuffles the elements of the specified char array. * The shuffling is performed in-place, meaning the original array is modified. * * @param a the char array to be shuffled */ public static void shuffle(final char[] a) { shuffle(a, RAND); } /** * Shuffles the elements of the specified char array using the specified random number generator. * The shuffling is performed in-place, meaning the original array is modified. * * @param a the char array to be shuffled * @param rnd the random number generator to use */ public static void shuffle(final char[] a, final Random rnd) { if (isEmpty(a) || a.length == 1) { return; } for (int i = a.length; i > 1; i--) { swap(a, i - 1, rnd.nextInt(i)); } } /** * Shuffles the elements of the specified byte array. * The shuffling is performed in-place, meaning the original array is modified. * * @param a the byte array to be shuffled */ public static void shuffle(final byte[] a) { shuffle(a, RAND); } /** * Shuffles the elements of the specified byte array using the specified random number generator. * The shuffling is performed in-place, meaning the original array is modified. * * @param a the byte array to be shuffled * @param rnd the random number generator to use */ public static void shuffle(final byte[] a, final Random rnd) { if (isEmpty(a) || a.length == 1) { return; } for (int i = a.length; i > 1; i--) { swap(a, i - 1, rnd.nextInt(i)); } } /** * Shuffles the elements of the specified short array. * The shuffling is performed in-place, meaning the original array is modified. * * @param a the short array to be shuffled */ public static void shuffle(final short[] a) { shuffle(a, RAND); } /** * Shuffles the elements of the specified short array using the specified random number generator. * The shuffling is performed in-place, meaning the original array is modified. * * @param a the short array to be shuffled * @param rnd the random number generator */ public static void shuffle(final short[] a, final Random rnd) { if (isEmpty(a) || a.length == 1) { return; } for (int i = a.length; i > 1; i--) { swap(a, i - 1, rnd.nextInt(i)); } } /** * Shuffles the elements of the specified int array. * The shuffling is performed in-place, meaning the original array is modified. * * @param a the int array to be shuffled */ public static void shuffle(final int[] a) { shuffle(a, RAND); } /** * Shuffles the elements of the specified int array using the specified random number generator. * The shuffling is performed in-place, meaning the original array is modified. * * @param a the int array to be shuffled * @param rnd the random number generator to use */ public static void shuffle(final int[] a, final Random rnd) { if (isEmpty(a) || a.length == 1) { return; } for (int i = a.length; i > 1; i--) { swap(a, i - 1, rnd.nextInt(i)); } } /** * Shuffles the elements of the specified long array. * The shuffling is performed in-place, meaning the original array is modified. * * @param a the long array to be shuffled */ public static void shuffle(final long[] a) { shuffle(a, RAND); } /** * Shuffles the elements of the specified long array using the specified random number generator. * The shuffling is performed in-place, meaning the original array is modified. * * @param a the long array to be shuffled * @param rnd the random number generator to use */ public static void shuffle(final long[] a, final Random rnd) { if (isEmpty(a) || a.length == 1) { return; } for (int i = a.length; i > 1; i--) { swap(a, i - 1, rnd.nextInt(i)); } } /** * Shuffles the elements of the specified float array. * The shuffling is performed in-place, meaning the original array is modified. * * @param a the float array to be shuffled */ public static void shuffle(final float[] a) { shuffle(a, RAND); } /** * Shuffles the elements of the specified float array using the specified random number generator. * The shuffling is performed in-place, meaning the original array is modified. * * @param a the float array to be shuffled * @param rnd the random number generator to use */ public static void shuffle(final float[] a, final Random rnd) { if (isEmpty(a) || a.length == 1) { return; } for (int i = a.length; i > 1; i--) { swap(a, i - 1, rnd.nextInt(i)); } } /** * Shuffles the elements of the specified double array. * The shuffling is performed in-place, meaning the original array is modified. * * @param a the double array to be shuffled */ public static void shuffle(final double[] a) { shuffle(a, RAND); } /** * Shuffles the elements of the specified double array using the specified random number generator. * The shuffling is performed in-place, meaning the original array is modified. * * @param a the double array to be shuffled * @param rnd the random number generator to use */ public static void shuffle(final double[] a, final Random rnd) { if (isEmpty(a) || a.length == 1) { return; } for (int i = a.length; i > 1; i--) { swap(a, i - 1, rnd.nextInt(i)); } } /** * Shuffles the elements of the specified object array. * The shuffling is performed in-place, meaning the original array is modified. * * @param a the object array to be shuffled */ public static void shuffle(final Object[] a) { shuffle(a, RAND); } /** * Shuffles the elements of the specified object array using the specified random number generator. * The shuffling is performed in-place, meaning the original array is modified. * * @param a the object array to be shuffled * @param rnd the random number generator to use */ public static void shuffle(final Object[] a, final Random rnd) { if (isEmpty(a) || a.length == 1) { return; } for (int i = a.length; i > 1; i--) { swap(a, i - 1, rnd.nextInt(i)); } } /** * Shuffles the elements of the specified list. * The shuffling is performed in-place, meaning the original list is modified. * * @param list the list to be shuffled * @see java.util.Collections#shuffle(List) */ public static void shuffle(final List list) { shuffle(list, RAND); } /** * Shuffles the elements of the specified list using the specified random number generator. * The shuffling is performed in-place, meaning the original list is modified. * * @param list the list to be shuffled * @param rnd the random number generator to use * @see java.util.Collections#shuffle(List, Random) */ public static void shuffle(final List list, final Random rnd) { if (isEmpty(list) || list.size() == 1) { return; } Collections.shuffle(list, rnd); } /** * Shuffles the elements of the specified collection that has a well-defined encounter order. * The shuffling is performed in-place, meaning the original collection is modified. * * @param c the collection to be shuffled. It should be a collection that has a well-defined encounter order. * @see #shuffle(List) * @see #shuffle(List, Random) * @see java.util.Collections#shuffle(List) */ @Beta @SuppressWarnings("rawtypes") public static void shuffle(final Collection c) { if (isEmpty(c) || c.size() < 2) { return; } if (c instanceof List) { shuffle((List) c); } else { final Object[] tmp = c.toArray(); shuffle(tmp); c.clear(); c.addAll((List) Arrays.asList(tmp)); } } /** * Shuffles the elements of the specified collection that has a well-defined encounter order using the specified random number generator. * The shuffling is performed in-place, meaning the original collection is modified. * * @param c the collection to be shuffled. It should be a collection that has a well-defined encounter order. * @param rnd the random number generator to use * @see #shuffle(List) * @see #shuffle(List, Random) * @see java.util.Collections#shuffle(List, Random) */ @Beta @SuppressWarnings("rawtypes") public static void shuffle(final Collection c, final Random rnd) { if (isEmpty(c) || c.size() < 2) { return; } if (c instanceof List) { shuffle((List) c, rnd); } else { final Object[] tmp = c.toArray(); shuffle(tmp, rnd); c.clear(); c.addAll((List) Arrays.asList(tmp)); } } /** * Swaps the elements at the specified positions in the specified boolean array. * * @param a the boolean array in which to swap elements * @param i the index of one element to be swapped * @param j the index of the other element to be swapped */ public static void swap(final boolean[] a, final int i, final int j) { final boolean tmp = a[i]; a[i] = a[j]; a[j] = tmp; } /** * Swaps the elements at the specified positions in the specified char array. * * @param a the char array in which to swap elements * @param i the index of one element to be swapped * @param j the index of the other element to be swapped */ public static void swap(final char[] a, final int i, final int j) { final char tmp = a[i]; a[i] = a[j]; a[j] = tmp; } /** * Swaps the elements at the specified positions in the specified byte array. * * @param a the byte array in which to swap elements * @param i the index of one element to be swapped * @param j the index of the other element to be swapped */ public static void swap(final byte[] a, final int i, final int j) { final byte tmp = a[i]; a[i] = a[j]; a[j] = tmp; } /** * Swaps the elements at the specified positions in the specified short array. * * @param a the short array in which to swap elements * @param i the index of one element to be swapped * @param j the index of the other element to be swapped */ public static void swap(final short[] a, final int i, final int j) { final short tmp = a[i]; a[i] = a[j]; a[j] = tmp; } /** * Swaps the elements at the specified positions in the specified int array. * * @param a the int array in which to swap elements * @param i the index of one element to be swapped * @param j the index of the other element to be swapped */ public static void swap(final int[] a, final int i, final int j) { final int tmp = a[i]; a[i] = a[j]; a[j] = tmp; } /** * Swaps the elements at the specified positions in the specified long array. * * @param a the long array in which to swap elements * @param i the index of one element to be swapped * @param j the index of the other element to be swapped */ public static void swap(final long[] a, final int i, final int j) { final long tmp = a[i]; a[i] = a[j]; a[j] = tmp; } /** * Swaps the elements at the specified positions in the specified float array. * * @param a the float array in which to swap elements * @param i the index of one element to be swapped * @param j the index of the other element to be swapped */ public static void swap(final float[] a, final int i, final int j) { final float tmp = a[i]; a[i] = a[j]; a[j] = tmp; } /** * Swaps the elements at the specified positions in the specified double array. * * @param a the double array in which to swap elements * @param i the index of one element to be swapped * @param j the index of the other element to be swapped */ public static void swap(final double[] a, final int i, final int j) { final double tmp = a[i]; a[i] = a[j]; a[j] = tmp; } /** * Swaps the elements at the specified positions in the specified Object array. * * @param a the Object array in which to swap elements * @param i the index of one element to be swapped * @param j the index of the other element to be swapped */ public static void swap(final Object[] a, final int i, final int j) { final Object tmp = a[i]; a[i] = a[j]; a[j] = tmp; } /** * Swaps the elements at the specified positions in the specified list. * * @param list the list in which to swap elements * @param i the index of one element to be swapped * @param j the index of the other element to be swapped * @see java.util.Collections#swap(List, int, int) */ public static void swap(final List list, final int i, final int j) { Collections.swap(list, i, j); } /** * Swaps the left and right elements in the specified pair. * * @param the type of the elements in the pair * @param pair the pair whose elements are to be swapped */ public static void swap(final Pair pair) { pair.set(pair.right, pair.left); } /** * Swaps the left and right elements in the specified pair if the specified predicate is {@code true}. * * @param the type of the elements in the pair * @param pair the pair whose elements are to be swapped * @param predicate the predicate to determine if the elements should be swapped * @return {@code true} if the left and right elements are swapped, otherwise {@code false} */ public static boolean swapIf(final Pair pair, final Predicate> predicate) { if (predicate.test(pair)) { pair.set(pair.right, pair.left); return true; } return false; } /** * Swaps the left and right elements in the specified triple. * * @param the type of the elements in the triple * @param triple the triple whose elements are to be swapped */ public static void swap(final Triple triple) { final T left = triple.left; triple.setLeft(triple.right); triple.setRight(left); } /** * Swaps the left and right elements in the specified triple if the specified predicate is {@code true}. * * @param the type of the elements in the triple * @param triple the triple whose elements are to be swapped * @param predicate the predicate to determine if the elements should be swapped * @return {@code true} if the left and right elements are swapped, otherwise {@code false} */ public static boolean swapIf(final Triple triple, final Predicate> predicate) { if (predicate.test(triple)) { final T left = triple.left; triple.setLeft(triple.right); triple.setRight(left); return true; } return false; } /** * Fills the specified boolean array with the specified value. * * @param a the boolean array to be filled * @param val the boolean value to fill the array with * @see Arrays#fill(boolean[], boolean) */ public static void fill(final boolean[] a, final boolean val) { if (isEmpty(a)) { return; } Arrays.fill(a, val); } /** * Fills the specified boolean array with the specified value from the specified fromIndex (inclusive) to the specified toIndex (exclusive). * * @param a the boolean array to be filled * @param fromIndex the index to start filling (inclusive) * @param toIndex the index to stop filling (exclusive) * @param val the boolean value to fill the array with * @throws IndexOutOfBoundsException if the fromIndex or toIndex is out of bounds * @see Arrays#fill(boolean[], int, int, boolean) */ public static void fill(final boolean[] a, final int fromIndex, final int toIndex, final boolean val) { checkFromToIndex(fromIndex, toIndex, len(a)); if (fromIndex == toIndex) { return; } Arrays.fill(a, fromIndex, toIndex, val); } /** * Fills the specified char array with the specified value. * * @param a the char array to be filled * @param val the char value to fill the array with * @see Arrays#fill(char[], char) */ public static void fill(final char[] a, final char val) { if (isEmpty(a)) { return; } Arrays.fill(a, val); } /** * Fills the specified char array with the specified value from the specified fromIndex (inclusive) to the specified toIndex (exclusive). * * @param a the char array to be filled * @param fromIndex the index to start filling (inclusive) * @param toIndex the index to stop filling (exclusive) * @param val the char value to fill the array with * @throws IndexOutOfBoundsException if the fromIndex or toIndex is out of bounds * @see Arrays#fill(char[], int, int, char) */ public static void fill(final char[] a, final int fromIndex, final int toIndex, final char val) { checkFromToIndex(fromIndex, toIndex, len(a)); if (fromIndex == toIndex) { return; } Arrays.fill(a, fromIndex, toIndex, val); } /** * Fills the specified byte array with the specified value. * * @param a the byte array to be filled * @param val the byte value to fill the array with * @see Arrays#fill(byte[], byte) */ public static void fill(final byte[] a, final byte val) { if (isEmpty(a)) { return; } Arrays.fill(a, val); } /** * Fills the specified byte array with the specified value from the specified fromIndex (inclusive) to the specified toIndex (exclusive). * * @param a the byte array to be filled * @param fromIndex the index to start filling (inclusive) * @param toIndex the index to stop filling (exclusive) * @param val the byte value to fill the array with * @throws IndexOutOfBoundsException if the fromIndex or toIndex is out of bounds * @see Arrays#fill(byte[], int, int, byte) */ public static void fill(final byte[] a, final int fromIndex, final int toIndex, final byte val) { checkFromToIndex(fromIndex, toIndex, len(a)); if (fromIndex == toIndex) { return; } Arrays.fill(a, fromIndex, toIndex, val); } /** * Fills the specified short array with the specified value. * * @param a the short array to be filled * @param val the short value to fill the array with * @see Arrays#fill(short[], short) */ public static void fill(final short[] a, final short val) { if (isEmpty(a)) { return; } Arrays.fill(a, val); } /** * Fills the specified short array with the specified value from the specified fromIndex (inclusive) to the specified toIndex (exclusive). * * @param a the short array to be filled * @param fromIndex the index to start filling (inclusive) * @param toIndex the index to stop filling (exclusive) * @param val the short value to fill the array with * @throws IndexOutOfBoundsException if the fromIndex or toIndex is out of bounds * @see Arrays#fill(short[], int, int, short) */ public static void fill(final short[] a, final int fromIndex, final int toIndex, final short val) { checkFromToIndex(fromIndex, toIndex, len(a)); if (fromIndex == toIndex) { return; } Arrays.fill(a, fromIndex, toIndex, val); } /** * Fills the specified int array with the specified value. * * @param a the int array to be filled * @param val the int value to fill the array with * @see Arrays#fill(int[], int) */ public static void fill(final int[] a, final int val) { if (isEmpty(a)) { return; } Arrays.fill(a, val); } /** * Fills the specified int array with the specified value from the specified fromIndex (inclusive) to the specified toIndex (exclusive). * * @param a the int array to be filled * @param fromIndex the index to start filling (inclusive) * @param toIndex the index to stop filling (exclusive) * @param val the int value to fill the array with * @throws IndexOutOfBoundsException if the fromIndex or toIndex is out of bounds * @see Arrays#fill(int[], int, int, int) */ public static void fill(final int[] a, final int fromIndex, final int toIndex, final int val) { checkFromToIndex(fromIndex, toIndex, len(a)); if (fromIndex == toIndex) { return; } Arrays.fill(a, fromIndex, toIndex, val); } /** * Fills the specified long array with the specified value. * * @param a the long array to be filled * @param val the long value to fill the array with * @see Arrays#fill(long[], long) */ public static void fill(final long[] a, final long val) { if (isEmpty(a)) { return; } Arrays.fill(a, val); } /** * Fills the specified long array with the specified value from the specified fromIndex (inclusive) to the specified toIndex (exclusive). * * @param a the long array to be filled * @param fromIndex the index to start filling (inclusive) * @param toIndex the index to stop filling (exclusive) * @param val the long value to fill the array with * @throws IndexOutOfBoundsException if the fromIndex or toIndex is out of bounds * @see Arrays#fill(long[], int, int, long) */ public static void fill(final long[] a, final int fromIndex, final int toIndex, final long val) { checkFromToIndex(fromIndex, toIndex, len(a)); if (fromIndex == toIndex) { return; } Arrays.fill(a, fromIndex, toIndex, val); } /** * Fills the specified float array with the specified value. * * @param a the float array to be filled * @param val the float value to fill the array with * @see Arrays#fill(float[], float) */ public static void fill(final float[] a, final float val) { if (isEmpty(a)) { return; } Arrays.fill(a, val); } /** * Fills the specified float array with the specified value from the specified fromIndex (inclusive) to the specified toIndex (exclusive). * * @param a the float array to be filled * @param fromIndex the index to start filling (inclusive) * @param toIndex the index to stop filling (exclusive) * @param val the float value to fill the array with * @throws IndexOutOfBoundsException if the fromIndex or toIndex is out of bounds * @throws ArrayIndexOutOfBoundsException if {@code fromIndex < 0} or {@code toIndex > a.length} * @see Arrays#fill(float[], int, int, float) */ public static void fill(final float[] a, final int fromIndex, final int toIndex, final float val) { checkFromToIndex(fromIndex, toIndex, len(a)); if (fromIndex == toIndex) { return; } Arrays.fill(a, fromIndex, toIndex, val); } /** * Fills the specified double array with the specified value. * * @param a the double array to be filled * @param val the double value to fill the array with * @see Arrays#fill(double[], double) */ public static void fill(final double[] a, final double val) { if (isEmpty(a)) { return; } Arrays.fill(a, val); } /** * Fills the specified double array with the specified value from the specified fromIndex (inclusive) to the specified toIndex (exclusive). * * @param a the double array to be filled * @param fromIndex the index to start filling (inclusive) * @param toIndex the index to stop filling (exclusive) * @param val the double value to fill the array with * @throws IndexOutOfBoundsException if the fromIndex or toIndex is out of bounds * @see Arrays#fill(double[], int, int, double) */ public static void fill(final double[] a, final int fromIndex, final int toIndex, final double val) { checkFromToIndex(fromIndex, toIndex, len(a)); if (fromIndex == toIndex) { return; } Arrays.fill(a, fromIndex, toIndex, val); } /** * Fills the specified Object array with the specified value. * * @param a the Object array to be filled * @param val the Object value to fill the array with * @see Arrays#fill(Object[], Object) * @see N#setAll(Object[], IntFunction) * @see N#replaceAll(Object[], UnaryOperator) * @see Iterables#fill(Object[], Supplier) * @see Iterables#fill(Object[], int, int, Supplier) */ public static void fill(final T[] a, final T val) { if (isEmpty(a)) { return; } for (int i = 0, len = a.length; i < len; i++) { a[i] = val; } } /** * Fills the specified Object array with the specified value from the specified fromIndex (inclusive) to the specified toIndex (exclusive). * * @param a the Object array to be filled * @param fromIndex the index to start filling (inclusive) * @param toIndex the index to stop filling (exclusive) * @param val the Object value to fill the array with * @throws IndexOutOfBoundsException if the fromIndex or toIndex is out of bounds * @see Arrays#fill(Object[], int, int, Object) * @see Iterables#fill(Object[], Supplier) * @see Iterables#fill(Object[], int, int, Supplier) */ public static void fill(final T[] a, final int fromIndex, final int toIndex, final T val) { checkFromToIndex(fromIndex, toIndex, len(a)); if (fromIndex == toIndex) { return; } for (int i = fromIndex; i < toIndex; i++) { a[i] = val; } } /** * Fills the specified list with the specified value. * * @param the type of elements in the list * @param list the list to be filled * @param val the value to fill the list with * @throws IllegalArgumentException if the specified list is null * @see Iterables#fill(List, Supplier) * @see Iterables#fill(List, int, int, Supplier) * @see N#setAll(List, IntFunction) * @see N#replaceAll(List, UnaryOperator) * @see #fill(List, int, int, Object) * @see #padLeft(List, int, Object) * @see #padRight(Collection, int, Object) */ public static void fill(final List list, final T val) throws IllegalArgumentException { checkArgNotNull(list, cs.list); fill(list, 0, list.size(), val); } /** * Fills the specified list with the specified value from the specified start index to the specified end index. * The list will be extended automatically if the size of the list is less than the specified toIndex. * * @param the type of elements in the list * @param list the list to be filled * @param fromIndex the starting index (inclusive) to begin filling * @param toIndex the ending index (exclusive) to stop filling * @param val the value to fill the list with * @throws IllegalArgumentException if the specified list is null * @throws IndexOutOfBoundsException if the specified indices are out of range * @see Iterables#fill(List, Supplier) * @see Iterables#fill(List, int, int, Supplier) * @see #fill(List, Object) * @see #padLeft(List, int, Object) * @see #padRight(Collection, int, Object) */ public static void fill(final List list, final int fromIndex, final int toIndex, final T val) throws IllegalArgumentException, IndexOutOfBoundsException { checkArgNotNull(list, cs.list); checkFromToIndex(fromIndex, toIndex, Integer.MAX_VALUE); final int size = list.size(); if (size < toIndex) { if (fromIndex < size) { for (int i = fromIndex; i < size; i++) { list.set(i, val); } } else { for (int i = size; i < fromIndex; i++) { list.add(null); } } for (int i = 0, len = toIndex - list.size(); i < len; i++) { list.add(val); } } else { if (toIndex - fromIndex < FILL_THRESHOLD || list instanceof RandomAccess) { for (int i = fromIndex; i < toIndex; i++) { list.set(i, val); } } else { final ListIterator itr = list.listIterator(fromIndex); for (int i = fromIndex; i < toIndex; i++) { itr.next(); itr.set(val); } } } } /** * Fills the properties of the specified bean with random values. * * @param bean the bean object with getter/setter methods to be filled with random values * @throws IllegalArgumentException if the specified bean is {@code null} or the bean class is not a valid JavaBean */ public static void fill(final Object bean) throws IllegalArgumentException { TestUtil.fill(bean); } /** * Fills the properties of a new instance of the specified bean class with random values. * * @param the type of the bean * @param beanClass the class of the bean to be filled * @return a new instance of the specified bean class with properties filled with random values * @throws IllegalArgumentException if the specified beanClass is {@code null} or the bean class is not a valid JavaBean */ public static T fill(final Class beanClass) throws IllegalArgumentException { return TestUtil.fill(beanClass); } /** * Returns a list of new instances of the specified bean class with properties filled with random values. * * @param the type of the bean * @param beanClass the class of the bean to be filled * @param count the number of instances to create and fill * @return a list of new instances of the specified bean class with properties filled with random values * @throws IllegalArgumentException if the specified beanClass is {@code null} or the bean class is not a valid JavaBean */ public static List fill(final Class beanClass, final int count) throws IllegalArgumentException { return TestUtil.fill(beanClass, count); } // /** // * // * @param // * @param c // * @param valueToAdd // * @param minSize // * @return // */ // @Beta // public static boolean append(final Collection c, final T valueToAdd, final int minSize) { // return padRight(c, minSize, valueToAdd); // } // // /** // * // * @param // * @param list // * @param valueToAdd // * @param fromIndex // * @param minSize // * @return // */ // @Beta // public static boolean append(final List list, final T valueToAdd, final int fromIndex, final int minSize) { // return padLeft(list, minSize, valueToAdd); // } /** * Appends the provided object to the beginning of the list till the list has at least the specified minimum size. * * @param the type of the elements in the list * @param list the list to be padded * @param minSize the minimum size the list should have after this operation * @param objToAdd the object to add to the list if it is smaller than the specified minimum size * @return {@code true} if the list was modified as a result of this operation, {@code false} otherwise * @throws IllegalArgumentException if the list is {@code null} or the minimum size is negative * @see #padRight(Collection, int, Object) * @see Strings#padStart(String, int) * @see Strings#padStart(String, int, char) */ @SuppressWarnings("rawtypes") public static boolean padLeft(final List list, final int minSize, final T objToAdd) throws IllegalArgumentException { checkArgNotNull(list, cs.list); checkArgNotNegative(minSize, cs.minSize); final int size = size(list); if (size < minSize) { final int elementCountToAdd = minSize - size; final Object[] a = new Object[elementCountToAdd]; if (objToAdd != null) { fill(a, objToAdd); } list.addAll(0, (List) Arrays.asList(a)); return true; } return false; } /** * Appends the provided object to the end of the collection until the collection has at least the specified minimum size. * * @param the type of elements in the collection * @param c the collection to be padded * @param minSize the minimum size the collection should have after padding * @param objToAdd the object to be added to the collection * @return {@code true} if the collection was modified, {@code false} otherwise * @throws IllegalArgumentException if the collection is {@code null} or the minimum size is negative * @see #padLeft(List, int, Object) * @see #fill(List, Object) * @see #fill(List, int, int, Object) */ @SuppressWarnings("rawtypes") public static boolean padRight(final Collection c, final int minSize, final T objToAdd) throws IllegalArgumentException { checkArgNotNull(c, cs.collection); checkArgNotNegative(minSize, cs.minSize); final int size = size(c); if (size < minSize) { final int elementCountToAdd = minSize - size; final Object[] a = new Object[elementCountToAdd]; if (objToAdd != null) { fill(a, objToAdd); } c.addAll((Collection) Arrays.asList(a)); return true; } return false; } /** * Repeats the provided value a specified number of times. * * @param the type of the value to be repeated * @param value the value to be repeated * @param n the number of times to repeat the value * @return a list containing the repeated values * @throws IllegalArgumentException if the specified number of repetitions is negative * @see Iterators#repeat(Object, int) * @see Collections#nCopies(int, Object) */ public static List repeat(final T value, final int n) throws IllegalArgumentException { checkArgNotNegative(n, cs.n); final List res = new ArrayList<>(n); fill(res, 0, n, value); return res; } /** * Repeats each element in the specified Collection n times one by one. * *
     * 
     * repeatElements(asList(1, 2, 3), 2) => [1, 1, 2, 2, 3, 3]
     * 
     * 
* * @param the type of the elements in the collection * @param c the collection whose elements are to be repeated * @param n the number of times to repeat the elements * @return a list containing the repeated elements * @throws IllegalArgumentException if the specified collection is {@code null} or empty, or specified number of repetitions is negative * @see Iterators#repeatElements(Collection, long) */ public static List repeatElements(final Collection c, final int n) throws IllegalArgumentException { checkArgNotNegative(n, cs.n); if (n == 0 || isEmpty(c)) { return new ArrayList<>(); } final List result = new ArrayList<>(c.size() * n); for (final T e : c) { for (int i = 0; i < n; i++) { result.add(e); } } return result; } /** * Repeats the entire specified Collection {@code n} times. * *
     * 
     * repeatCollection(asList(1, 2, 3), 2) => [1, 2, 3, 1, 2, 3]
     * 
     * 
* * @param the type of the elements in the collection * @param c the collection whose elements are to be repeated * @param n the number of times to repeat the elements * @return a list containing the repeated elements * @throws IllegalArgumentException if the specified collection is {@code null} or empty, or specified number of repetitions is negative * @see Iterators#repeatCollection(Collection, long) */ public static List repeatCollection(final Collection c, final int n) throws IllegalArgumentException { checkArgNotNegative(n, cs.n); if (n == 0 || isEmpty(c)) { return new ArrayList<>(); } final List result = new ArrayList<>(c.size() * n); for (int i = 0; i < n; i++) { result.addAll(c); } return result; } /** * Repeats each element in the specified Collection n times one by one till reach the specified size. * *
     * 
     * repeatElementsToSize(asList(1, 2, 3), 5) => [1, 1, 2, 2, 3]
     * 
     * 
* * @param the type of the elements in the collection * @param c the collection whose elements are to be repeated * @param size the target size of the resulting list * @return a list containing the repeated elements * @throws IllegalArgumentException if the specified collection is {@code null} or empty, or the specified size is negative * @throws IllegalArgumentException * @see Iterators#repeatElementsToSize(Collection, long) */ public static List repeatElementsToSize(final Collection c, final int size) throws IllegalArgumentException { checkArgument(size == 0 || notEmpty(c), "Collection cannot be empty or null when size > 0"); checkArgNotNegative(size, cs.size); if (size == 0 || isEmpty(c)) { return new ArrayList<>(); } final int n = size / c.size(); int mod = size % c.size(); final List result = new ArrayList<>(size); for (final T e : c) { for (int i = 0, cnt = mod-- > 0 ? n + 1 : n; i < cnt; i++) { result.add(e); } if (result.size() == size) { break; } } return result; } /** * Repeats the entire specified Collection {@code n} times till reach the specified size. * *
     * 
     * repeatCollectionToSize(asList(1, 2, 3), 5) => [1, 2, 3, 1, 2]
     * 
     * 
* * @param the type of the elements in the collection * @param c the collection whose elements are to be repeated * @param size the target size of the resulting list * @return a list containing the repeated elements * @throws IllegalArgumentException if the specified collection is {@code null} or empty, or the specified size is negative * @see Iterators#repeatCollectionToSize(Collection, long) */ public static List repeatCollectionToSize(final Collection c, final int size) throws IllegalArgumentException { checkArgument(size == 0 || notEmpty(c), "Collection cannot be empty or null when size > 0"); checkArgNotNegative(size, cs.size); if (size == 0 || isEmpty(c)) { return new ArrayList<>(); } final List result = new ArrayList<>(size); while (result.size() < size) { if (c.size() <= size - result.size()) { result.addAll(c); } else { final Iterator iter = c.iterator(); for (int i = 0, cnt = size - result.size(); i < cnt; i++) { result.add(iter.next()); } } } return result; } /** * Copies all the elements from the source list into the destination list. * After the operation, the index of each copied element in the destination list * will be identical to its index in the source list. The destination list must * be at least as long as the source list. If it is longer, the remaining elements * in the destination list are unaffected. * * This method runs in linear time. * * @param the type of elements in the lists * @param src the source list from which elements are to be copied * @param dest the destination list to which elements are to be copied * @throws IndexOutOfBoundsException if the destination list is too small to contain the entire source list * @throws UnsupportedOperationException if the destination list's list-iterator does not support the set operation * @see java.util.Collections#copy(List, List) */ public static void copy(final List src, final List dest) { if (isEmpty(src)) { return; } if (src.size() > dest.size()) { throw new IndexOutOfBoundsException("Source does not fit in dest"); } Collections.copy(dest, src); } /** * Copies a portion of one list into another. The portion to be copied begins at the index srcPos in the source list and spans length elements. * The elements are copied into the destination list starting at position destPos. Both source and destination positions are zero-based. * * @param the type of elements in the lists * @param src the source list from which to copy elements * @param srcPos the starting position in the source list * @param dest the destination list into which to copy elements * @param destPos the starting position in the destination list * @param length the number of elements to be copied * @throws IndexOutOfBoundsException if copying would cause access of data outside list bounds */ public static void copy(final List src, final int srcPos, final List dest, final int destPos, final int length) throws IndexOutOfBoundsException { checkFromToIndex(srcPos, srcPos + length, size(src)); checkFromToIndex(destPos, destPos + length, size(dest)); if (isEmpty(src) && srcPos == 0 && length == 0) { return; } if (src instanceof RandomAccess && dest instanceof RandomAccess) { for (int i = 0; i < length; i++) { dest.set(destPos + i, src.get(srcPos + i)); } } else { final ListIterator srcIterator = src.listIterator(); final ListIterator destIterator = dest.listIterator(); int idx = 0; while (idx < srcPos) { srcIterator.next(); idx++; } idx = 0; while (idx < destPos) { destIterator.next(); idx++; } for (int i = 0; i < length; i++) { destIterator.next(); destIterator.set(srcIterator.next()); } } } /** * Copies elements from the source boolean array to the destination boolean array. * * @param src the source array from which elements are to be copied * @param srcPos starting position in the source array * @param dest the destination array to which elements are to be copied * @param destPos starting position in the destination array * @param length the number of array elements to be copied * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds * @see System#arraycopy(Object, int, Object, int, int) */ public static void copy(final boolean[] src, final int srcPos, final boolean[] dest, final int destPos, final int length) throws IndexOutOfBoundsException { checkFromToIndex(srcPos, srcPos + length, len(src)); checkFromToIndex(destPos, destPos + length, len(dest)); if (isEmpty(src) && srcPos == 0 && length == 0) { return; } if (length < MIN_SIZE_FOR_COPY_ALL) { // for same array copy. if (destPos > srcPos) { //noinspection ManualArrayCopy for (int i = length - 1; i >= 0; i--) { dest[destPos + i] = src[srcPos + i]; } } else { //noinspection ManualArrayCopy for (int i = 0; i < length; i++) { dest[destPos + i] = src[srcPos + i]; } } } else { System.arraycopy(src, srcPos, dest, destPos, length); } } /** * Copies elements from the source char array to the destination char array. * * @param src the source array from which elements are to be copied * @param srcPos starting position in the source array * @param dest the destination array to which elements are to be copied * @param destPos starting position in the destination array * @param length the number of array elements to be copied * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds * @see System#arraycopy(Object, int, Object, int, int) */ public static void copy(final char[] src, final int srcPos, final char[] dest, final int destPos, final int length) throws IndexOutOfBoundsException { checkFromToIndex(srcPos, srcPos + length, len(src)); checkFromToIndex(destPos, destPos + length, len(dest)); if (isEmpty(src) && srcPos == 0 && length == 0) { return; } if (length < MIN_SIZE_FOR_COPY_ALL) { // for same array copy. if (destPos > srcPos) { //noinspection ManualArrayCopy for (int i = length - 1; i >= 0; i--) { dest[destPos + i] = src[srcPos + i]; } } else { //noinspection ManualArrayCopy for (int i = 0; i < length; i++) { dest[destPos + i] = src[srcPos + i]; } } } else { System.arraycopy(src, srcPos, dest, destPos, length); } } /** * Copies elements from the source byte array to the destination byte array. * * @param src the source array from which elements are to be copied * @param srcPos starting position in the source array * @param dest the destination array to which elements are to be copied * @param destPos starting position in the destination array * @param length the number of array elements to be copied * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds * @see System#arraycopy(Object, int, Object, int, int) */ public static void copy(final byte[] src, final int srcPos, final byte[] dest, final int destPos, final int length) throws IndexOutOfBoundsException { checkFromToIndex(srcPos, srcPos + length, len(src)); checkFromToIndex(destPos, destPos + length, len(dest)); if (isEmpty(src) && srcPos == 0 && length == 0) { return; } if (length < MIN_SIZE_FOR_COPY_ALL) { // for same array copy. if (destPos > srcPos) { //noinspection ManualArrayCopy for (int i = length - 1; i >= 0; i--) { dest[destPos + i] = src[srcPos + i]; } } else { //noinspection ManualArrayCopy for (int i = 0; i < length; i++) { dest[destPos + i] = src[srcPos + i]; } } } else { System.arraycopy(src, srcPos, dest, destPos, length); } } /** * Copies elements from the source short array to the destination short array. * * @param src the source array from which elements are to be copied * @param srcPos starting position in the source array * @param dest the destination array to which elements are to be copied * @param destPos starting position in the destination array * @param length the number of array elements to be copied * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds * @see System#arraycopy(Object, int, Object, int, int) */ public static void copy(final short[] src, final int srcPos, final short[] dest, final int destPos, final int length) throws IndexOutOfBoundsException { checkFromToIndex(srcPos, srcPos + length, len(src)); checkFromToIndex(destPos, destPos + length, len(dest)); if (isEmpty(src) && srcPos == 0 && length == 0) { return; } if (length < MIN_SIZE_FOR_COPY_ALL) { // for same array copy. if (destPos > srcPos) { //noinspection ManualArrayCopy for (int i = length - 1; i >= 0; i--) { dest[destPos + i] = src[srcPos + i]; } } else { //noinspection ManualArrayCopy for (int i = 0; i < length; i++) { dest[destPos + i] = src[srcPos + i]; } } } else { System.arraycopy(src, srcPos, dest, destPos, length); } } /** * Copies elements from the source int array to the destination int array. * * @param src the source array from which elements are to be copied * @param srcPos starting position in the source array * @param dest the destination array to which elements are to be copied * @param destPos starting position in the destination array * @param length the number of array elements to be copied * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds * @see System#arraycopy(Object, int, Object, int, int) */ public static void copy(final int[] src, final int srcPos, final int[] dest, final int destPos, final int length) throws IndexOutOfBoundsException { checkFromToIndex(srcPos, srcPos + length, len(src)); checkFromToIndex(destPos, destPos + length, len(dest)); if (isEmpty(src) && srcPos == 0 && length == 0) { return; } if (length < MIN_SIZE_FOR_COPY_ALL) { // for same array copy. if (destPos > srcPos) { //noinspection ManualArrayCopy for (int i = length - 1; i >= 0; i--) { dest[destPos + i] = src[srcPos + i]; } } else { //noinspection ManualArrayCopy for (int i = 0; i < length; i++) { dest[destPos + i] = src[srcPos + i]; } } } else { System.arraycopy(src, srcPos, dest, destPos, length); } } /** * Copies elements from the source long array to the destination long array. * * @param src the source array from which elements are to be copied * @param srcPos starting position in the source array * @param dest the destination array to which elements are to be copied * @param destPos starting position in the destination array * @param length the number of array elements to be copied * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds * @see System#arraycopy(Object, int, Object, int, int) */ public static void copy(final long[] src, final int srcPos, final long[] dest, final int destPos, final int length) throws IndexOutOfBoundsException { checkFromToIndex(srcPos, srcPos + length, len(src)); checkFromToIndex(destPos, destPos + length, len(dest)); if (isEmpty(src) && srcPos == 0 && length == 0) { return; } if (length < MIN_SIZE_FOR_COPY_ALL) { // for same array copy. if (destPos > srcPos) { //noinspection ManualArrayCopy for (int i = length - 1; i >= 0; i--) { dest[destPos + i] = src[srcPos + i]; } } else { //noinspection ManualArrayCopy for (int i = 0; i < length; i++) { dest[destPos + i] = src[srcPos + i]; } } } else { System.arraycopy(src, srcPos, dest, destPos, length); } } /** * Copies elements from the source float array to the destination float array. * * @param src the source array from which elements are to be copied * @param srcPos starting position in the source array * @param dest the destination array to which elements are to be copied * @param destPos starting position in the destination array * @param length the number of array elements to be copied * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds * @see System#arraycopy(Object, int, Object, int, int) */ public static void copy(final float[] src, final int srcPos, final float[] dest, final int destPos, final int length) throws IndexOutOfBoundsException { checkFromToIndex(srcPos, srcPos + length, len(src)); checkFromToIndex(destPos, destPos + length, len(dest)); if (isEmpty(src) && srcPos == 0 && length == 0) { return; } if (length < MIN_SIZE_FOR_COPY_ALL) { // for same array copy. if (destPos > srcPos) { //noinspection ManualArrayCopy for (int i = length - 1; i >= 0; i--) { dest[destPos + i] = src[srcPos + i]; } } else { //noinspection ManualArrayCopy for (int i = 0; i < length; i++) { dest[destPos + i] = src[srcPos + i]; } } } else { System.arraycopy(src, srcPos, dest, destPos, length); } } /** * Copies elements from the source double array to the destination double array. * * @param src the source array from which elements are to be copied * @param srcPos starting position in the source array * @param dest the destination array to which elements are to be copied * @param destPos starting position in the destination array * @param length the number of array elements to be copied * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds * @see System#arraycopy(Object, int, Object, int, int) */ public static void copy(final double[] src, final int srcPos, final double[] dest, final int destPos, final int length) throws IndexOutOfBoundsException { checkFromToIndex(srcPos, srcPos + length, len(src)); checkFromToIndex(destPos, destPos + length, len(dest)); if (isEmpty(src) && srcPos == 0 && length == 0) { return; } if (length < MIN_SIZE_FOR_COPY_ALL) { // for same array copy. if (destPos > srcPos) { //noinspection ManualArrayCopy for (int i = length - 1; i >= 0; i--) { dest[destPos + i] = src[srcPos + i]; } } else { //noinspection ManualArrayCopy for (int i = 0; i < length; i++) { dest[destPos + i] = src[srcPos + i]; } } } else { System.arraycopy(src, srcPos, dest, destPos, length); } } /** * Copies elements from the source array to the destination array. * * @param src the source array from which elements are to be copied * @param srcPos starting position in the source array * @param dest the destination array to which elements are to be copied * @param destPos starting position in the destination array * @param length the number of array elements to be copied * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds * @see System#arraycopy(Object, int, Object, int, int) */ public static void copy(final Object[] src, final int srcPos, final Object[] dest, final int destPos, final int length) throws IndexOutOfBoundsException { checkFromToIndex(srcPos, srcPos + length, len(src)); checkFromToIndex(destPos, destPos + length, len(dest)); if (isEmpty(src) && srcPos == 0 && length == 0) { return; } if (length < MIN_SIZE_FOR_COPY_ALL) { // for same array copy. if (destPos > srcPos) { //noinspection ManualArrayCopy for (int i = length - 1; i >= 0; i--) { dest[destPos + i] = src[srcPos + i]; } } else { //noinspection ManualArrayCopy for (int i = 0; i < length; i++) { dest[destPos + i] = src[srcPos + i]; } } } else { System.arraycopy(src, srcPos, dest, destPos, length); } } /** * Copies elements from the source array to the destination array. * * @param src the source array from which elements are to be copied * @param srcPos starting position in the source array * @param dest the destination array to which elements are to be copied * @param destPos starting position in the destination array * @param length the number of array elements to be copied * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds * @see System#arraycopy(Object, int, Object, int, int) */ public static void copy(final Object src, final int srcPos, final Object dest, final int destPos, final int length) throws IndexOutOfBoundsException { checkFromToIndex(srcPos, srcPos + length, Array.getLength(src)); checkFromToIndex(destPos, destPos + length, Array.getLength(dest)); //noinspection SuspiciousSystemArraycopy System.arraycopy(src, srcPos, dest, destPos, length); } /** * Returns a new boolean array containing a copy of the original array, * truncated or padded with {@code false} (if necessary) so the copy has the specified length. * * @param original the array to be copied * @param newLength the length of the copy to be returned * @return a new boolean array containing a copy of the original array * @throws IllegalArgumentException if the specified new length is negative * @see Arrays#copyOf(boolean[], int) */ public static boolean[] copyOf(final boolean[] original, final int newLength) { checkArgNotNegative(newLength, cs.newLength); if (newLength == original.length) { return original.clone(); } final boolean[] copy = new boolean[newLength]; if (notEmpty(original)) { copy(original, 0, copy, 0, Math.min(original.length, newLength)); } return copy; } /** * Returns a new char array containing a copy of the original array, * truncated or padded with default value (if necessary) so the copy has the specified length. * * @param original the array to be copied * @param newLength the length of the copy to be returned * @return a new char array containing a copy of the original array * @throws IllegalArgumentException if the specified new length is negative * @see Arrays#copyOf(char[], int) */ public static char[] copyOf(final char[] original, final int newLength) { checkArgNotNegative(newLength, cs.newLength); if (newLength == original.length) { return original.clone(); } final char[] copy = new char[newLength]; if (notEmpty(original)) { copy(original, 0, copy, 0, Math.min(original.length, newLength)); } return copy; } /** * Returns a new byte array containing a copy of the original array, * truncated or padded with default value (if necessary) so the copy has the specified length. * * @param original the array to be copied * @param newLength the length of the copy to be returned * @return a new byte array containing a copy of the original array * @throws IllegalArgumentException if the specified new length is negative * @see Arrays#copyOf(byte[], int) */ public static byte[] copyOf(final byte[] original, final int newLength) { checkArgNotNegative(newLength, cs.newLength); if (newLength == original.length) { return original.clone(); } final byte[] copy = new byte[newLength]; if (notEmpty(original)) { copy(original, 0, copy, 0, Math.min(original.length, newLength)); } return copy; } /** * Returns a new short array containing a copy of the original array, * truncated or padded with default value (if necessary) so the copy has the specified length. * * @param original the array to be copied * @param newLength the length of the copy to be returned * @return a new short array containing a copy of the original array * @throws IllegalArgumentException if the specified new length is negative * @see Arrays#copyOf(short[], int) */ public static short[] copyOf(final short[] original, final int newLength) { checkArgNotNegative(newLength, cs.newLength); if (newLength == original.length) { return original.clone(); } final short[] copy = new short[newLength]; if (notEmpty(original)) { copy(original, 0, copy, 0, Math.min(original.length, newLength)); } return copy; } /** * Returns a new int array containing a copy of the original array, * truncated or padded with default value (if necessary) so the copy has the specified length. * * @param original the array to be copied * @param newLength the length of the copy to be returned * @return a new int array containing a copy of the original array * @throws IllegalArgumentException if the specified new length is negative * @see Arrays#copyOf(int[], int) */ public static int[] copyOf(final int[] original, final int newLength) { checkArgNotNegative(newLength, cs.newLength); if (newLength == original.length) { return original.clone(); } final int[] copy = new int[newLength]; if (notEmpty(original)) { copy(original, 0, copy, 0, Math.min(original.length, newLength)); } return copy; } /** * Returns a new long array containing a copy of the original array, * truncated or padded with default value (if necessary) so the copy has the specified length. * * @param original the array to be copied * @param newLength the length of the copy to be returned * @return a new long array containing a copy of the original array * @throws IllegalArgumentException if the specified new length is negative * @see Arrays#copyOf(long[], int) */ public static long[] copyOf(final long[] original, final int newLength) { checkArgNotNegative(newLength, cs.newLength); if (newLength == original.length) { return original.clone(); } final long[] copy = new long[newLength]; if (notEmpty(original)) { copy(original, 0, copy, 0, Math.min(original.length, newLength)); } return copy; } /** * Returns a new float array containing a copy of the original array, * truncated or padded with default value (if necessary) so the copy has the specified length. * * @param original the array to be copied * @param newLength the length of the copy to be returned * @return a new float array containing a copy of the original array * @throws IllegalArgumentException if the specified new length is negative * @see Arrays#copyOf(float[], int) */ public static float[] copyOf(final float[] original, final int newLength) { checkArgNotNegative(newLength, cs.newLength); if (newLength == original.length) { return original.clone(); } final float[] copy = new float[newLength]; if (notEmpty(original)) { copy(original, 0, copy, 0, Math.min(original.length, newLength)); } return copy; } /** * Returns a new double array containing a copy of the original array, * truncated or padded with default value (if necessary) so the copy has the specified length. * * @param original the array to be copied * @param newLength the length of the copy to be returned * @return a new double array containing a copy of the original array * @throws IllegalArgumentException if the specified new length is negative * @see Arrays#copyOf(double[], int) */ public static double[] copyOf(final double[] original, final int newLength) { checkArgNotNegative(newLength, cs.newLength); if (newLength == original.length) { return original.clone(); } final double[] copy = new double[newLength]; if (notEmpty(original)) { copy(original, 0, copy, 0, Math.min(original.length, newLength)); } return copy; } /** * Returns a new Object array containing a copy of the original array, * truncated or padded with {@code null} (if necessary) so the copy has the specified length. * * @param the type of the elements in the array * @param original the array to be copied * @param newLength the length of the copy to be returned * @return a new Object array containing a copy of the original array * @throws IllegalArgumentException if the specified new length is negative * @throws NullPointerException if {@code original} is null * @see Arrays#copyOf(Object[], int) */ public static T[] copyOf(final T[] original, final int newLength) { checkArgNotNegative(newLength, cs.newLength); if (newLength == original.length) { return original.clone(); } return (T[]) copyOf(original, newLength, original.getClass()); } /** * Returns a new array containing a copy of the original array, truncated or padded with {@code null} (if necessary) so the copy has the specified length. * * @param the type of the elements in the array * @param the type of the elements in the original array * @param original the array to be copied * @param newLength the length of the copy to be returned * @param newType the class of the copy to be returned * @return a new array containing a copy of the original array * @throws IllegalArgumentException if the specified new length is negative * @see Arrays#copyOf(Object[], int) */ public static T[] copyOf(final U[] original, final int newLength, final Class newType) { checkArgNotNegative(newLength, cs.newLength); final T[] copy = Object[].class.equals(newType) ? (T[]) new Object[newLength] : (T[]) newArray(newType.getComponentType(), newLength); if (notEmpty(original)) { copy(original, 0, copy, 0, Math.min(original.length, newLength)); } return copy; } /** * Returns a new boolean array containing a copy of the specified range of the original array. * * @param original the array from which a range is to be copied * @param fromIndex the initial index of the range to be copied, inclusive * @param toIndex the final index of the range to be copied, exclusive * @return a new boolean array containing the specified range from the original array * @throws IndexOutOfBoundsException if fromIndex is negative or larger than toIndex, or toIndex is larger than the length of array * @throws NullPointerException if original is null * @see Arrays#copyOfRange(boolean[], int, int) */ public static boolean[] copyOfRange(final boolean[] original, final int fromIndex, final int toIndex) { checkFromToIndex(fromIndex, toIndex, original.length); if (fromIndex == 0 && toIndex == original.length) { return original.clone(); } final int newLength = toIndex - fromIndex; final boolean[] copy = new boolean[newLength]; copy(original, fromIndex, copy, 0, Math.min(original.length - fromIndex, newLength)); return copy; } /** * Returns a new boolean array containing a copy of the specified range of the original array, with elements selected at intervals defined by the step parameter. * If step negative, the elements will be copied in reverse order. * * @param original the array from which a range is to be copied * @param fromIndex the initial index of the range to be copied, inclusive * @param toIndex the final index of the range to be copied, exclusive * @param step the interval between elements to be copied * @return a new boolean array containing the specified range from the original array * @throws IndexOutOfBoundsException if fromIndex is negative or larger than toIndex, or toIndex is larger than the length of array * @throws IllegalArgumentException if step is zero * @throws NullPointerException if original is null * @see #copyOfRange(int[], int, int, int) */ public static boolean[] copyOfRange(final boolean[] original, int fromIndex, final int toIndex, final int step) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex < toIndex ? fromIndex : (toIndex == -1 ? 0 : toIndex), Math.max(fromIndex, toIndex), original.length); if (step == 0) { throw new IllegalArgumentException("The input parameter 'by' cannot be zero"); } if (fromIndex == toIndex || fromIndex < toIndex != step > 0) { return EMPTY_BOOLEAN_ARRAY; } if (step == 1) { return copyOfRange(original, fromIndex, toIndex); } fromIndex = fromIndex > toIndex ? N.min(original.length - 1, fromIndex) : fromIndex; final int len = (toIndex - fromIndex) / step + ((toIndex - fromIndex) % step == 0 ? 0 : 1); final boolean[] copy = new boolean[len]; for (int i = 0, j = fromIndex; i < len; i++, j += step) { copy[i] = original[j]; } return copy; } /** * Returns a new char array containing a copy of the specified range of the original array. * * @param original the array from which a range is to be copied * @param fromIndex the initial index of the range to be copied, inclusive * @param toIndex the final index of the range to be copied, exclusive * @return a new char array containing the specified range from the original array * @throws IndexOutOfBoundsException if fromIndex is negative or larger than toIndex, or toIndex is larger than the length of array * @throws NullPointerException if original is null * @see Arrays#copyOfRange(char[], int, int) */ public static char[] copyOfRange(final char[] original, final int fromIndex, final int toIndex) { checkFromToIndex(fromIndex, toIndex, original.length); if (fromIndex == 0 && toIndex == original.length) { return original.clone(); } final int newLength = toIndex - fromIndex; final char[] copy = new char[newLength]; copy(original, fromIndex, copy, 0, Math.min(original.length - fromIndex, newLength)); return copy; } /** * Returns a new char array containing a copy of the specified range of the original array, with elements selected at intervals defined by the step parameter. * If step negative, the elements will be copied in reverse order. * * @param original the array from which a range is to be copied * @param fromIndex the initial index of the range to be copied, inclusive * @param toIndex the final index of the range to be copied, exclusive * @param step the interval between elements to be copied * @return a new char array containing the specified range from the original array * @throws IndexOutOfBoundsException if fromIndex is negative or larger than toIndex, or toIndex is larger than the length of array * @throws IllegalArgumentException if step is zero * @throws NullPointerException if original is null * @see #copyOfRange(int[], int, int, int) */ public static char[] copyOfRange(final char[] original, int fromIndex, final int toIndex, final int step) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex < toIndex ? fromIndex : (toIndex == -1 ? 0 : toIndex), Math.max(fromIndex, toIndex), original.length); if (step == 0) { throw new IllegalArgumentException("The input parameter 'by' cannot be zero"); } if (fromIndex == toIndex || fromIndex < toIndex != step > 0) { return EMPTY_CHAR_ARRAY; } if (step == 1) { return copyOfRange(original, fromIndex, toIndex); } fromIndex = fromIndex > toIndex ? N.min(original.length - 1, fromIndex) : fromIndex; final int len = (toIndex - fromIndex) / step + ((toIndex - fromIndex) % step == 0 ? 0 : 1); final char[] copy = new char[len]; for (int i = 0, j = fromIndex; i < len; i++, j += step) { copy[i] = original[j]; } return copy; } /** * Returns a new byte array containing a copy of the specified range of the original array. * * @param original the array from which a range is to be copied * @param fromIndex the initial index of the range to be copied, inclusive * @param toIndex the final index of the range to be copied, exclusive * @return a new byte array containing the specified range from the original array * @throws IndexOutOfBoundsException if fromIndex is negative or larger than toIndex, or toIndex is larger than the length of array * @throws NullPointerException if original is null * @see Arrays#copyOfRange(byte[], int, int) */ public static byte[] copyOfRange(final byte[] original, final int fromIndex, final int toIndex) { checkFromToIndex(fromIndex, toIndex, original.length); if (fromIndex == 0 && toIndex == original.length) { return original.clone(); } final int newLength = toIndex - fromIndex; final byte[] copy = new byte[newLength]; copy(original, fromIndex, copy, 0, Math.min(original.length - fromIndex, newLength)); return copy; } /** * Returns a new byte array containing a copy of the specified range of the original array, with elements selected at intervals defined by the step parameter. * If step negative, the elements will be copied in reverse order. * * @param original the array from which a range is to be copied * @param fromIndex the initial index of the range to be copied, inclusive * @param toIndex the final index of the range to be copied, exclusive * @param step the interval between elements to be copied * @return a new byte array containing the specified range from the original array * @throws IndexOutOfBoundsException if fromIndex is negative or larger than toIndex, or toIndex is larger than the length of array * @throws IllegalArgumentException if step is zero * @throws NullPointerException if original is null * @see #copyOfRange(int[], int, int, int) */ public static byte[] copyOfRange(final byte[] original, int fromIndex, final int toIndex, final int step) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex < toIndex ? fromIndex : (toIndex == -1 ? 0 : toIndex), Math.max(fromIndex, toIndex), original.length); if (step == 0) { throw new IllegalArgumentException("The input parameter 'by' cannot be zero"); } if (fromIndex == toIndex || fromIndex < toIndex != step > 0) { return EMPTY_BYTE_ARRAY; } if (step == 1) { return copyOfRange(original, fromIndex, toIndex); } fromIndex = fromIndex > toIndex ? N.min(original.length - 1, fromIndex) : fromIndex; final int len = (toIndex - fromIndex) / step + ((toIndex - fromIndex) % step == 0 ? 0 : 1); final byte[] copy = new byte[len]; for (int i = 0, j = fromIndex; i < len; i++, j += step) { copy[i] = original[j]; } return copy; } /** * Returns a new short array containing a copy of the specified range of the original array. * * @param original the array from which a range is to be copied * @param fromIndex the initial index of the range to be copied, inclusive * @param toIndex the final index of the range to be copied, exclusive * @return a new short array containing the specified range from the original array * @throws IndexOutOfBoundsException if fromIndex is negative or larger than toIndex, or toIndex is larger than the length of array * @throws NullPointerException if original is null * @see Arrays#copyOfRange(short[], int, int) */ public static short[] copyOfRange(final short[] original, final int fromIndex, final int toIndex) { checkFromToIndex(fromIndex, toIndex, original.length); if (fromIndex == 0 && toIndex == original.length) { return original.clone(); } final int newLength = toIndex - fromIndex; final short[] copy = new short[newLength]; copy(original, fromIndex, copy, 0, Math.min(original.length - fromIndex, newLength)); return copy; } /** * Returns a new short array containing a copy of the specified range of the original array, with elements selected at intervals defined by the step parameter. * If step negative, the elements will be copied in reverse order. * * @param original the array from which a range is to be copied * @param fromIndex the initial index of the range to be copied, inclusive * @param toIndex the final index of the range to be copied, exclusive * @param step the interval between elements to be copied * @return a new short array containing the specified range from the original array * @throws IndexOutOfBoundsException if fromIndex is negative or larger than toIndex, or toIndex is larger than the length of array * @throws IllegalArgumentException if step is zero * @throws NullPointerException if original is null * @see #copyOfRange(int[], int, int, int) */ public static short[] copyOfRange(final short[] original, int fromIndex, final int toIndex, final int step) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex < toIndex ? fromIndex : (toIndex == -1 ? 0 : toIndex), Math.max(fromIndex, toIndex), original.length); if (step == 0) { throw new IllegalArgumentException("The input parameter 'by' cannot be zero"); } if (fromIndex == toIndex || fromIndex < toIndex != step > 0) { return EMPTY_SHORT_ARRAY; } if (step == 1) { return copyOfRange(original, fromIndex, toIndex); } fromIndex = fromIndex > toIndex ? N.min(original.length - 1, fromIndex) : fromIndex; final int len = (toIndex - fromIndex) / step + ((toIndex - fromIndex) % step == 0 ? 0 : 1); final short[] copy = new short[len]; for (int i = 0, j = fromIndex; i < len; i++, j += step) { copy[i] = original[j]; } return copy; } /** * Returns a new int array containing a copy of the specified range of the original array. * * @param original the array from which a range is to be copied * @param fromIndex the initial index of the range to be copied, inclusive * @param toIndex the final index of the range to be copied, exclusive * @return a new int array containing the specified range from the original array * @throws IndexOutOfBoundsException if fromIndex is negative or larger than toIndex, or toIndex is larger than the length of array * @throws NullPointerException if original is null * @see Arrays#copyOfRange(int[], int, int) */ public static int[] copyOfRange(final int[] original, final int fromIndex, final int toIndex) { checkFromToIndex(fromIndex, toIndex, original.length); if (fromIndex == 0 && toIndex == original.length) { return original.clone(); } final int newLength = toIndex - fromIndex; final int[] copy = new int[newLength]; copy(original, fromIndex, copy, 0, Math.min(original.length - fromIndex, newLength)); return copy; } /** * Returns a new int array containing a copy of the specified range of the original array, with elements selected at intervals defined by the step parameter. * If step negative, the elements will be copied in reverse order. * *
     * 
     * int[] a = { 0, 1, 2, 3, 4, 5 };
     * copyOfRange(a, 1, 5, 1)); // [1, 2, 3, 4]
     * copyOfRange(a, 1, 5, 2); // [1, 3]
     *
     * copyOfRange(a, 5, 1, -1); // [5, 4, 3, 2]
     * copyOfRange(a, 5, 1, -2); // [5, 3]
     * copyOfRange(a, 5, -1, -1); // [5, 4, 3, 2, 1, 0]
     * copyOfRange(a, 6, -1, -1); // [5, 4, 3, 2, 1, 0]
     * 
     * 
* * @param original the array from which a range is to be copied * @param fromIndex the initial index of the range to be copied, inclusive * @param toIndex the final index of the range to be copied, exclusive * @param step the interval between elements to be copied * @return a new int array containing the specified range from the original array * @throws IndexOutOfBoundsException if fromIndex is negative or larger than toIndex, or toIndex is larger than the length of array * @throws IllegalArgumentException if step is zero * @throws NullPointerException if original is null */ public static int[] copyOfRange(final int[] original, int fromIndex, final int toIndex, final int step) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex < toIndex ? fromIndex : (toIndex == -1 ? 0 : toIndex), Math.max(fromIndex, toIndex), original.length); if (step == 0) { throw new IllegalArgumentException("The input parameter 'by' cannot be zero"); } if (fromIndex == toIndex || fromIndex < toIndex != step > 0) { return EMPTY_INT_ARRAY; } if (step == 1) { return copyOfRange(original, fromIndex, toIndex); } fromIndex = fromIndex > toIndex ? N.min(original.length - 1, fromIndex) : fromIndex; final int len = (toIndex - fromIndex) / step + ((toIndex - fromIndex) % step == 0 ? 0 : 1); final int[] copy = new int[len]; for (int i = 0, j = fromIndex; i < len; i++, j += step) { copy[i] = original[j]; } return copy; } /** * Returns a new long array containing a copy of the specified range of the original array. * * @param original the array from which a range is to be copied * @param fromIndex the initial index of the range to be copied, inclusive * @param toIndex the final index of the range to be copied, exclusive * @return a new long array containing the specified range from the original array * @throws IndexOutOfBoundsException if fromIndex is negative or larger than toIndex, or toIndex is larger than the length of array * @throws NullPointerException if original is null * @see Arrays#copyOfRange(long[], int, int) */ public static long[] copyOfRange(final long[] original, final int fromIndex, final int toIndex) { checkFromToIndex(fromIndex, toIndex, original.length); if (fromIndex == 0 && toIndex == original.length) { return original.clone(); } final int newLength = toIndex - fromIndex; final long[] copy = new long[newLength]; copy(original, fromIndex, copy, 0, Math.min(original.length - fromIndex, newLength)); return copy; } /** * Returns a new long array containing a copy of the specified range of the original array, with elements selected at intervals defined by the step parameter. * If step negative, the elements will be copied in reverse order. * * @param original the array from which a range is to be copied * @param fromIndex the initial index of the range to be copied, inclusive * @param toIndex the final index of the range to be copied, exclusive * @param step the interval between elements to be copied * @return a new long array containing the specified range from the original array * @throws IndexOutOfBoundsException if fromIndex is negative or larger than toIndex, or toIndex is larger than the length of array * @throws IllegalArgumentException if step is zero * @throws NullPointerException if original is null * @see #copyOfRange(int[], int, int, int) */ public static long[] copyOfRange(final long[] original, int fromIndex, final int toIndex, final int step) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex < toIndex ? fromIndex : (toIndex == -1 ? 0 : toIndex), Math.max(fromIndex, toIndex), original.length); if (step == 0) { throw new IllegalArgumentException("The input parameter 'by' cannot be zero"); } if (fromIndex == toIndex || fromIndex < toIndex != step > 0) { return EMPTY_LONG_ARRAY; } if (step == 1) { return copyOfRange(original, fromIndex, toIndex); } fromIndex = fromIndex > toIndex ? N.min(original.length - 1, fromIndex) : fromIndex; final int len = (toIndex - fromIndex) / step + ((toIndex - fromIndex) % step == 0 ? 0 : 1); final long[] copy = new long[len]; for (int i = 0, j = fromIndex; i < len; i++, j += step) { copy[i] = original[j]; } return copy; } /** * Returns a new float array containing a copy of the specified range of the original array. * * @param original the array from which a range is to be copied * @param fromIndex the initial index of the range to be copied, inclusive * @param toIndex the final index of the range to be copied, exclusive * @return a new float array containing the specified range from the original array * @throws IndexOutOfBoundsException if fromIndex is negative or larger than toIndex, or toIndex is larger than the length of array * @throws NullPointerException if original is null * @see Arrays#copyOfRange(float[], int, int) */ public static float[] copyOfRange(final float[] original, final int fromIndex, final int toIndex) { checkFromToIndex(fromIndex, toIndex, original.length); if (fromIndex == 0 && toIndex == original.length) { return original.clone(); } final int newLength = toIndex - fromIndex; final float[] copy = new float[newLength]; copy(original, fromIndex, copy, 0, Math.min(original.length - fromIndex, newLength)); return copy; } /** * Returns a new float array containing a copy of the specified range of the original array, with elements selected at intervals defined by the step parameter. * If step negative, the elements will be copied in reverse order. * * @param original the array from which a range is to be copied * @param fromIndex the initial index of the range to be copied, inclusive * @param toIndex the final index of the range to be copied, exclusive * @param step the interval between elements to be copied * @return a new float array containing the specified range from the original array * @throws IndexOutOfBoundsException if fromIndex is negative or larger than toIndex, or toIndex is larger than the length of array * @throws IllegalArgumentException if step is zero * @throws NullPointerException if original is null * @see #copyOfRange(int[], int, int, int) */ public static float[] copyOfRange(final float[] original, int fromIndex, final int toIndex, final int step) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex < toIndex ? fromIndex : (toIndex == -1 ? 0 : toIndex), Math.max(fromIndex, toIndex), original.length); if (step == 0) { throw new IllegalArgumentException("The input parameter 'by' cannot be zero"); } if (fromIndex == toIndex || fromIndex < toIndex != step > 0) { return EMPTY_FLOAT_ARRAY; } if (step == 1) { return copyOfRange(original, fromIndex, toIndex); } fromIndex = fromIndex > toIndex ? N.min(original.length - 1, fromIndex) : fromIndex; final int len = (toIndex - fromIndex) / step + ((toIndex - fromIndex) % step == 0 ? 0 : 1); final float[] copy = new float[len]; for (int i = 0, j = fromIndex; i < len; i++, j += step) { copy[i] = original[j]; } return copy; } /** * Returns a new double array containing a copy of the specified range of the original array. * * @param original the array from which a range is to be copied * @param fromIndex the initial index of the range to be copied, inclusive * @param toIndex the final index of the range to be copied, exclusive * @return a new double array containing the specified range from the original array * @throws IndexOutOfBoundsException if fromIndex is negative or larger than toIndex, or toIndex is larger than the length of array * @throws NullPointerException if original is null * @see Arrays#copyOfRange(double[], int, int) */ public static double[] copyOfRange(final double[] original, final int fromIndex, final int toIndex) { checkFromToIndex(fromIndex, toIndex, original.length); if (fromIndex == 0 && toIndex == original.length) { return original.clone(); } final int newLength = toIndex - fromIndex; final double[] copy = new double[newLength]; copy(original, fromIndex, copy, 0, Math.min(original.length - fromIndex, newLength)); return copy; } /** * Returns a new double array containing a copy of the specified range of the original array, with elements selected at intervals defined by the step parameter. * If step negative, the elements will be copied in reverse order. * * @param original the array from which a range is to be copied * @param fromIndex the initial index of the range to be copied, inclusive * @param toIndex the final index of the range to be copied, exclusive * @param step the interval between elements to be copied * @return a new double array containing the specified range from the original array * @throws IndexOutOfBoundsException if fromIndex is negative or larger than toIndex, or toIndex is larger than the length of array * @throws IllegalArgumentException if step is zero * @throws NullPointerException if original is null * @see #copyOfRange(int[], int, int, int) */ public static double[] copyOfRange(final double[] original, int fromIndex, final int toIndex, final int step) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex < toIndex ? fromIndex : (toIndex == -1 ? 0 : toIndex), Math.max(fromIndex, toIndex), original.length); if (step == 0) { throw new IllegalArgumentException("The input parameter 'by' cannot be zero"); } if (fromIndex == toIndex || fromIndex < toIndex != step > 0) { return EMPTY_DOUBLE_ARRAY; } if (step == 1) { return copyOfRange(original, fromIndex, toIndex); } fromIndex = fromIndex > toIndex ? N.min(original.length - 1, fromIndex) : fromIndex; final int len = (toIndex - fromIndex) / step + ((toIndex - fromIndex) % step == 0 ? 0 : 1); final double[] copy = new double[len]; for (int i = 0, j = fromIndex; i < len; i++, j += step) { copy[i] = original[j]; } return copy; } /** * Returns a new Object array containing a copy of the specified range of the original array. * * @param the type of the elements in the array * @param original the array from which a range is to be copied * @param fromIndex the initial index of the range to be copied, inclusive * @param toIndex the final index of the range to be copied, exclusive * @return a new Object array containing the specified range from the original array * @throws IndexOutOfBoundsException if fromIndex is negative or larger than toIndex, or toIndex is larger than the length of array * @throws NullPointerException if original is null * @see Arrays#copyOfRange(Object[], int, int) */ public static T[] copyOfRange(final T[] original, final int fromIndex, final int toIndex) { checkFromToIndex(fromIndex, toIndex, original.length); if (fromIndex == 0 && toIndex == original.length) { return original.clone(); } return copyOfRange(original, fromIndex, toIndex, (Class) original.getClass()); } /** * Returns a new Object array containing a copy of the specified range of the original array, with elements selected at intervals defined by the step parameter. * If step negative, the elements will be copied in reverse order. * * @param the type of the elements in the array * @param original the array from which a range is to be copied * @param fromIndex the initial index of the range to be copied, inclusive * @param toIndex the final index of the range to be copied, exclusive * @param step the interval between elements to be copied * @return a new Object array containing the specified range from the original array * @throws IndexOutOfBoundsException if fromIndex is negative or larger than toIndex, or toIndex is larger than the length of array * @throws IllegalArgumentException if step is zero * @throws NullPointerException if original is null * @see #copyOfRange(int[], int, int, int) */ public static T[] copyOfRange(final T[] original, final int fromIndex, final int toIndex, final int step) { return copyOfRange(original, fromIndex, toIndex, step, (Class) original.getClass()); } /** * Returns a new array containing a copy of the specified range of the original array. * * @param the type of the elements in the new array * @param the type of the elements in the original array * @param original the array from which a range is to be copied * @param fromIndex the initial index of the range to be copied, inclusive * @param toIndex the final index of the range to be copied, exclusive * @param newType the class of the new array * @return a new array containing the specified range from the original array * @throws IndexOutOfBoundsException if fromIndex is negative or larger than toIndex, or toIndex is larger than the length of array * @throws NullPointerException if original is null * @see Arrays#copyOfRange(Object[], int, int, Class) */ public static T[] copyOfRange(final U[] original, final int fromIndex, final int toIndex, final Class newType) { final int newLength = toIndex - fromIndex; final T[] copy = Object[].class.equals(newType) ? (T[]) new Object[newLength] : (T[]) newArray(newType.getComponentType(), newLength); copy(original, fromIndex, copy, 0, Math.min(original.length - fromIndex, newLength)); return copy; } /** * Returns a new array containing a copy of the specified range of the original array, with elements selected at intervals defined by the step parameter. * If step negative, the elements will be copied in reverse order. * * @param the type of the elements in the new array * @param original the array from which a range is to be copied * @param fromIndex the initial index of the range to be copied, inclusive * @param toIndex the final index of the range to be copied, exclusive * @param step the interval between elements to be copied * @param newType the class of the new array * @return a new array containing the specified range from the original array * @throws IndexOutOfBoundsException if fromIndex is negative or larger than toIndex, or toIndex is larger than the length of array * @throws IllegalArgumentException if step is zero * @throws NullPointerException if original is null * @see #copyOfRange(int[], int, int, int) */ public static T[] copyOfRange(final T[] original, int fromIndex, final int toIndex, final int step, final Class newType) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex < toIndex ? fromIndex : (toIndex == -1 ? 0 : toIndex), Math.max(fromIndex, toIndex), original.length); if (step == 0) { throw new IllegalArgumentException("The input parameter 'by' cannot be zero"); } if (fromIndex == toIndex || fromIndex < toIndex != step > 0) { return Object[].class.equals(newType) ? (T[]) new Object[0] : (T[]) newArray(newType.getComponentType(), 0); } if (step == 1) { return copyOfRange(original, fromIndex, toIndex); } fromIndex = fromIndex > toIndex ? N.min(original.length - 1, fromIndex) : fromIndex; final int len = (toIndex - fromIndex) / step + ((toIndex - fromIndex) % step == 0 ? 0 : 1); final T[] copy = Object[].class.equals(newType) ? (T[]) new Object[len] : (T[]) newArray(newType.getComponentType(), len); for (int i = 0, j = fromIndex; i < len; i++, j += step) { copy[i] = original[j]; } return copy; } /** * Returns a new list containing a copy of the specified range of the original list. * * @param the type of elements in the list * @param c the list from which a range is to be copied * @param fromIndex the initial index of the range to be copied, inclusive * @param toIndex the final index of the range to be copied, exclusive * @return a new list containing the specified range from the original list * @throws IndexOutOfBoundsException if fromIndex is negative or larger than toIndex, toIndex is greater than the size of list * @throws NullPointerException if original is null */ public static List copyOfRange(final List c, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, c.size()); final List result = new ArrayList<>(toIndex - fromIndex); result.addAll(c.subList(fromIndex, toIndex)); return result; } /** * Returns a new list containing a copy of the specified range of the original list, with elements selected at intervals defined by the step parameter. * If step negative, the elements will be copied in reverse order. * * @param the type of elements in the list * @param c the list from which a range is to be copied * @param fromIndex the initial index of the range to be copied, inclusive * @param toIndex the final index of the range to be copied, exclusive * @param step the interval between elements to be copied * @return a new list containing the specified range from the original list * @throws IndexOutOfBoundsException if fromIndex is negative or larger than toIndex, toIndex is greater than the size of list * @throws IllegalArgumentException if step is zero * @throws NullPointerException if original is null * @see #copyOfRange(int[], int, int, int) */ @SuppressWarnings("deprecation") public static List copyOfRange(final List c, int fromIndex, final int toIndex, final int step) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex < toIndex ? fromIndex : (toIndex == -1 ? 0 : toIndex), Math.max(fromIndex, toIndex), c.size()); if (step == 0) { throw new IllegalArgumentException("The input parameter 'by' cannot be zero"); } if (fromIndex == toIndex || fromIndex < toIndex != step > 0) { return new ArrayList<>(); } if (step == 1) { return copyOfRange(c, fromIndex, toIndex); } fromIndex = fromIndex > toIndex ? N.min(c.size() - 1, fromIndex) : fromIndex; final int len = (toIndex - fromIndex) / step + ((toIndex - fromIndex) % step == 0 ? 0 : 1); List result = null; if (c instanceof RandomAccess) { result = new ArrayList<>(len); for (int i = 0, j = fromIndex; i < len; i++, j += step) { result.add(c.get(j)); } } else { final T[] a = (T[]) c.subList(fromIndex, toIndex).toArray(); result = InternalUtil.createList(copyOfRange(a, 0, a.length, step)); } return result; } /** * Returns a new string that is a substring of the specified string. * The substring begins at the specified fromIndex and extends to the character at index toIndex - 1. * Thus, the length of the substring is toIndex - fromIndex. * * @param str the original string from which a range is to be copied * @param fromIndex the beginning index, inclusive * @param toIndex the ending index, exclusive * @return the specified substring * @throws IndexOutOfBoundsException if the fromIndex is negative, toIndex is greater than the length of the string, or fromIndex is greater than toIndex */ public static String copyOfRange(final String str, final int fromIndex, final int toIndex) { final int len = len(str); checkFromIndexSize(fromIndex, toIndex, len); if (fromIndex == 0 && toIndex == len) { return Strings.EMPTY; } return str.substring(fromIndex, toIndex); } /** * Returns a new string that is a substring of the specified string, with characters selected at intervals defined by the step parameter. * If step negative, the characters will be copied in reverse order. * * @param str the original string from which a range is to be copied * @param fromIndex the beginning index, inclusive * @param toIndex the ending index, exclusive * @param step the interval between characters to be copied * @return the specified substring * @throws IndexOutOfBoundsException if the fromIndex is negative, toIndex is greater than the length of the string, or fromIndex is greater than toIndex * @throws IllegalArgumentException if step is zero * @see #copyOfRange(int[], int, int, int) */ @SuppressWarnings("deprecation") public static String copyOfRange(final String str, final int fromIndex, final int toIndex, final int step) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex < toIndex ? fromIndex : (toIndex == -1 ? 0 : toIndex), Math.max(fromIndex, toIndex), str.length()); if (step == 0) { throw new IllegalArgumentException("The input parameter 'by' cannot be zero"); } if (fromIndex == toIndex || fromIndex < toIndex != step > 0) { return Strings.EMPTY; } if (step == 1) { return copyOfRange(str, fromIndex, toIndex); } return String.valueOf(copyOfRange(InternalUtil.getCharsForReadOnly(str), fromIndex, toIndex, step)); } /** * Returns a new array that is a clone of the specified array, or {@code null} if the original array is {@code null}. * * @param original the array to be cloned * @return a clone of the original array, or {@code null} if the original array is null */ @MayReturnNull public static boolean[] clone(final boolean[] original) { if (original == null) { return null; // NOSONAR } return original.clone(); } /** * Returns a new array that is a clone of the specified array, or {@code null} if the original array is {@code null}. * * @param original the array to be cloned * @return a clone of the original array, or {@code null} if the original array is null */ @MayReturnNull public static char[] clone(final char[] original) { if (original == null) { return null; // NOSONAR } return original.clone(); } /** * Returns a new array that is a clone of the specified array, or {@code null} if the original array is {@code null}. * * @param original the array to be cloned * @return a clone of the original array, or {@code null} if the original array is null */ @MayReturnNull public static byte[] clone(final byte[] original) { if (original == null) { return null; // NOSONAR } return original.clone(); } /** * Returns a new array that is a clone of the specified array, or {@code null} if the original array is {@code null}. * * @param original the array to be cloned * @return a clone of the original array, or {@code null} if the original array is null */ @MayReturnNull public static short[] clone(final short[] original) { if (original == null) { return null; // NOSONAR } return original.clone(); } /** * Returns a new array that is a clone of the specified array, or {@code null} if the original array is {@code null}. * * @param original the array to be cloned * @return a clone of the original array, or {@code null} if the original array is null */ @MayReturnNull public static int[] clone(final int[] original) { if (original == null) { return null; // NOSONAR } return original.clone(); } /** * Returns a new array that is a clone of the specified array, or {@code null} if the original array is {@code null}. * * @param original the array to be cloned * @return a clone of the original array, or {@code null} if the original array is null */ @MayReturnNull public static long[] clone(final long[] original) { if (original == null) { return null; // NOSONAR } return original.clone(); } /** * Returns a new array that is a clone of the specified array, or {@code null} if the original array is {@code null}. * * @param original the array to be cloned * @return a clone of the original array, or {@code null} if the original array is null */ @MayReturnNull public static float[] clone(final float[] original) { if (original == null) { return null; // NOSONAR } return original.clone(); } /** * Returns a new array that is a clone of the specified array, or {@code null} if the original array is {@code null}. * * @param original the array to be cloned * @return a clone of the original array, or {@code null} if the original array is null */ @MayReturnNull public static double[] clone(final double[] original) { if (original == null) { return null; // NOSONAR } return original.clone(); } /** * Returns a new array that is a clone of the specified array, or {@code null} if the original array is {@code null}. * * @param original the array to be cloned * @return a clone of the original array, or {@code null} if the original array is null */ @MayReturnNull public static T[] clone(final T[] original) { if (original == null) { return null; // NOSONAR } return original.clone(); } /** * Clone the original array and its sub arrays. {@code null} is returned if the input array is {@code null}. * * @param original the 2D array to be cloned * @return a clone of the original 2D array, or {@code null} if the original array is null * @see #clone(boolean[]) */ @MayReturnNull public static boolean[][] clone(final boolean[][] original) { if (original == null) { return null; // NOSONAR } final boolean[][] cp = original.clone(); for (int i = 0, len = cp.length; i < len; i++) { cp[i] = clone(original[i]); } return cp; } /** * Clone the original array and its sub arrays. {@code null} is returned if the input array is {@code null}. * * @param original the 2D array to be cloned * @return a clone of the original 2D array, or {@code null} if the original array is null * @see #clone(char[]) */ @MayReturnNull public static char[][] clone(final char[][] original) { if (original == null) { return null; // NOSONAR } final char[][] cp = original.clone(); for (int i = 0, len = cp.length; i < len; i++) { cp[i] = clone(original[i]); } return cp; } /** * Clone the original array and its sub arrays. {@code null} is returned if the input array is {@code null}. * * @param original the 2D array to be cloned * @return a clone of the original 2D array, or {@code null} if the original array is null * @see #clone(byte[]) */ @MayReturnNull public static byte[][] clone(final byte[][] original) { if (original == null) { return null; // NOSONAR } final byte[][] cp = original.clone(); for (int i = 0, len = cp.length; i < len; i++) { cp[i] = clone(original[i]); } return cp; } /** * Clone the original array and its sub arrays. {@code null} is returned if the input array is {@code null}. * * @param original the 2D array to be cloned * @return a clone of the original 2D array, or {@code null} if the original array is null * @see #clone(short[]) */ @MayReturnNull public static short[][] clone(final short[][] original) { if (original == null) { return null; // NOSONAR } final short[][] cp = original.clone(); for (int i = 0, len = cp.length; i < len; i++) { cp[i] = clone(original[i]); } return cp; } /** * Clone the original array and its sub arrays. {@code null} is returned if the input array is {@code null}. * * @param original the 2D array to be cloned * @return a clone of the original 2D array, or {@code null} if the original array is null * @see #clone(int[]) */ @MayReturnNull public static int[][] clone(final int[][] original) { if (original == null) { return null; // NOSONAR } final int[][] cp = original.clone(); for (int i = 0, len = cp.length; i < len; i++) { cp[i] = clone(original[i]); } return cp; } /** * Clone the original array and its sub arrays. {@code null} is returned if the input array is {@code null}. * * @param original the 2D array to be cloned * @return a clone of the original 2D array, or {@code null} if the original array is null * @see #clone(long[]) */ @MayReturnNull public static long[][] clone(final long[][] original) { if (original == null) { return null; // NOSONAR } final long[][] cp = original.clone(); for (int i = 0, len = cp.length; i < len; i++) { cp[i] = clone(original[i]); } return cp; } /** * Clone the original array and its sub arrays. {@code null} is returned if the input array is {@code null}. * * @param original the 2D array to be cloned * @return a clone of the original 2D array, or {@code null} if the original array is null * @see #clone(float[]) */ @MayReturnNull public static float[][] clone(final float[][] original) { if (original == null) { return null; // NOSONAR } final float[][] cp = original.clone(); for (int i = 0, len = cp.length; i < len; i++) { cp[i] = clone(original[i]); } return cp; } /** * Clone the original array and its sub arrays. {@code null} is returned if the input array is {@code null}. * * @param original the 2D array to be cloned * @return a clone of the original 2D array, or {@code null} if the original array is null * @see #clone(double[]) */ @MayReturnNull public static double[][] clone(final double[][] original) { if (original == null) { return null; // NOSONAR } final double[][] cp = original.clone(); for (int i = 0, len = cp.length; i < len; i++) { cp[i] = clone(original[i]); } return cp; } /** * Clone the original array and its sub arrays. {@code null} is returned if the input array is {@code null}. * * @param original the 2D array to be cloned * @return a clone of the original 2D array, or {@code null} if the original array is null * @see #clone(Object[]) */ @MayReturnNull public static T[][] clone(final T[][] original) { if (original == null) { return null; // NOSONAR } final T[][] cp = original.clone(); for (int i = 0, len = cp.length; i < len; i++) { cp[i] = clone(original[i]); } return cp; } /** * Clone the original array and its sub arrays. {@code null} is returned if the input array is {@code null}. * * @param original the 3D array to be cloned * @return a clone of the original 3D array, or {@code null} if the original array is null * @see #clone(boolean[]) * @see #clone(boolean[][]) */ @MayReturnNull public static boolean[][][] clone(final boolean[][][] original) { if (original == null) { return null; // NOSONAR } final boolean[][][] cp = original.clone(); for (int i = 0, len = cp.length; i < len; i++) { cp[i] = clone(original[i]); } return cp; } /** * Clone the original array and its sub arrays. {@code null} is returned if the input array is {@code null}. * * @param original the 3D array to be cloned * @return a clone of the original 3D array, or {@code null} if the original array is null * @see #clone(char[]) * @see #clone(char[][]) */ @MayReturnNull public static char[][][] clone(final char[][][] original) { if (original == null) { return null; // NOSONAR } final char[][][] cp = original.clone(); for (int i = 0, len = cp.length; i < len; i++) { cp[i] = clone(original[i]); } return cp; } /** * Clone the original array and its sub arrays. {@code null} is returned if the input array is {@code null}. * * @param original the 3D array to be cloned * @return a clone of the original 3D array, or {@code null} if the original array is null * @see #clone(byte[]) * @see #clone(byte[][]) */ @MayReturnNull public static byte[][][] clone(final byte[][][] original) { if (original == null) { return null; // NOSONAR } final byte[][][] cp = original.clone(); for (int i = 0, len = cp.length; i < len; i++) { cp[i] = clone(original[i]); } return cp; } /** * Clone the original array and its sub arrays. {@code null} is returned if the input array is {@code null}. * * @param original the 3D array to be cloned * @return a clone of the original 3D array, or {@code null} if the original array is null * @see #clone(short[]) * @see #clone(short[][]) */ @MayReturnNull public static short[][][] clone(final short[][][] original) { if (original == null) { return null; // NOSONAR } final short[][][] cp = original.clone(); for (int i = 0, len = cp.length; i < len; i++) { cp[i] = clone(original[i]); } return cp; } /** * Clone the original array and its sub arrays. {@code null} is returned if the input array is {@code null}. * * @param original the 3D array to be cloned * @return a clone of the original 3D array, or {@code null} if the original array is null * @see #clone(int[]) * @see #clone(int[][]) */ @MayReturnNull public static int[][][] clone(final int[][][] original) { if (original == null) { return null; // NOSONAR } final int[][][] cp = original.clone(); for (int i = 0, len = cp.length; i < len; i++) { cp[i] = clone(original[i]); } return cp; } /** * Clone the original array and its sub arrays. {@code null} is returned if the input array is {@code null}. * * @param original the 3D array to be cloned * @return a clone of the original 3D array, or {@code null} if the original array is null * @see #clone(long[]) * @see #clone(long[][]) */ @MayReturnNull public static long[][][] clone(final long[][][] original) { if (original == null) { return null; // NOSONAR } final long[][][] cp = original.clone(); for (int i = 0, len = cp.length; i < len; i++) { cp[i] = clone(original[i]); } return cp; } /** * Clone the original array and its sub arrays. {@code null} is returned if the input array is {@code null}. * * @param original the 3D array to be cloned * @return a clone of the original 3D array, or {@code null} if the original array is null * @see #clone(float[]) * @see #clone(float[][]) */ @MayReturnNull public static float[][][] clone(final float[][][] original) { if (original == null) { return null; // NOSONAR } final float[][][] cp = original.clone(); for (int i = 0, len = cp.length; i < len; i++) { cp[i] = clone(original[i]); } return cp; } /** * Clone the original array and its sub arrays. {@code null} is returned if the input array is {@code null}. * * @param original the 3D array to be cloned * @return a clone of the original 3D array, or {@code null} if the original array is null * @see #clone(double[]) * @see #clone(double[][]) */ @MayReturnNull public static double[][][] clone(final double[][][] original) { if (original == null) { return null; // NOSONAR } final double[][][] cp = original.clone(); for (int i = 0, len = cp.length; i < len; i++) { cp[i] = clone(original[i]); } return cp; } /** * Clone the original array and its sub arrays. {@code null} is returned if the input array is {@code null}. * * @param original the 3D array to be cloned * @return a clone of the original 3D array, or {@code null} if the original array is null * @see #clone(Object[]) * @see #clone(Object[][]) */ @MayReturnNull public static T[][][] clone(final T[][][] original) { if (original == null) { return null; // NOSONAR } final T[][][] cp = original.clone(); for (int i = 0, len = cp.length; i < len; i++) { cp[i] = clone(original[i]); } return cp; } // /** // * // * @param // * @param a // * @param newType // * @return // */ // public static T[] copy(Object[] a, Class newType) { // if (isEmpty(a)) { // return newArray(newType.getComponentType(), 0); // } // // return copyOf(a, a.length, newType); // } // // /** // * // * @param // * @param a // * @param newType // * @return // */ // public static T[][] copy(Object[][] a, Class newType) { // final Class componentType = (Class) newType.getComponentType(); // // if (isEmpty(a)) { // return newArray(componentType, 0); // } // // final int len = len(a); // final T[][] result = newArray(componentType, len); // // for (int i = 0; i < len; i++) { // result[i] = copy(componentType, a[i]); // } // // return result; // } // // /** // * // * @param // * @param a // * @param newType // * @return // */ // public static T[][][] copy(Object[][][] a, Class newType) { // final Class componentType = (Class) newType.getComponentType(); // // if (isEmpty(a)) { // return newArray(componentType, 0); // } // // final int len = len(a); // final T[][][] result = newArray(componentType, len); // // for (int i = 0; i < len; i++) { // result[i] = copy(componentType, a[i]); // } // // return result; // } /** * Checks if the specified boolean array is sorted in ascending order. * * @param a the boolean array to be checked * @return {@code true} if the array is sorted in ascending order, {@code false} otherwise */ public static boolean isSorted(final boolean[] a) { final int len = len(a); if (len < 2) { return true; } else if (Boolean.compare(a[len - 1], a[0]) < 0) { return false; } for (int i = 1; i < len; i++) { if (Boolean.compare(a[i], a[i - 1]) < 0) { return false; } } return true; } /** * Checks if the specified range of the boolean array is sorted in ascending order. * * @param a the boolean array to be checked * @param fromIndex the starting index (inclusive) of the range to be checked * @param toIndex the ending index (exclusive) of the range to be checked * @return {@code true} if the specified range of the array is sorted in ascending order, {@code false} otherwise * @throws IndexOutOfBoundsException if the specified range is out of bounds */ public static boolean isSorted(final boolean[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { final int len = len(a); checkFromToIndex(fromIndex, toIndex, len); if (toIndex - fromIndex < 2) { return true; } else if (Boolean.compare(a[toIndex - 1], a[fromIndex]) < 0) { return false; } for (int i = fromIndex + 1; i < toIndex; i++) { if (Boolean.compare(a[i], a[i - 1]) < 0) { return false; } } return true; } /** * Checks if the specified char array is sorted in ascending order. * * @param a the char array to be checked * @return {@code true} if the array is sorted in ascending order, {@code false} otherwise */ public static boolean isSorted(final char[] a) { final int len = len(a); if (len < 2) { return true; } else if (a[len - 1] < a[0]) { return false; } for (int i = 1; i < len; i++) { if (a[i] < a[i - 1]) { return false; } } return true; } /** * Checks if the specified range of the char array is sorted in ascending order. * * @param a the array to be checked * @param fromIndex the starting index (inclusive) of the range to be checked * @param toIndex the ending index (exclusive) of the range to be checked * @return {@code true} if the specified range of the array is sorted in ascending order, {@code false} otherwise * @throws IndexOutOfBoundsException if the specified range is out of bounds */ public static boolean isSorted(final char[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); if (toIndex - fromIndex < 2) { return true; } else if (a[toIndex - 1] < a[fromIndex]) { return false; } for (int i = fromIndex + 1; i < toIndex; i++) { if (a[i] < a[i - 1]) { return false; } } return true; } /** * Checks if the specified byte array is sorted in ascending order. * * @param a the byte array to be checked * @return {@code true} if the array is sorted in ascending order, {@code false} otherwise */ public static boolean isSorted(final byte[] a) { final int len = len(a); if (len < 2) { return true; } else if (a[len - 1] < a[0]) { return false; } for (int i = 1; i < len; i++) { if (a[i] < a[i - 1]) { return false; } } return true; } /** * Checks if the specified range of the byte array is sorted in ascending order. * * @param a the array to be checked * @param fromIndex the starting index (inclusive) of the range to be checked * @param toIndex the ending index (exclusive) of the range to be checked * @return {@code true} if the specified range of the array is sorted in ascending order, {@code false} otherwise * @throws IndexOutOfBoundsException if the specified range is out of bounds */ public static boolean isSorted(final byte[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); if (toIndex - fromIndex < 2) { return true; } else if (a[toIndex - 1] < a[fromIndex]) { return false; } for (int i = fromIndex + 1; i < toIndex; i++) { if (a[i] < a[i - 1]) { return false; } } return true; } /** * Checks if the specified byte short is sorted in ascending order. * * @param a the short array to be checked * @return {@code true} if the array is sorted in ascending order, {@code false} otherwise */ public static boolean isSorted(final short[] a) { final int len = len(a); if (len < 2) { return true; } else if (a[len - 1] < a[0]) { return false; } for (int i = 1; i < len; i++) { if (a[i] < a[i - 1]) { return false; } } return true; } /** * Checks if the specified range of the short array is sorted in ascending order. * * @param a the array to be checked * @param fromIndex the starting index (inclusive) of the range to be checked * @param toIndex the ending index (exclusive) of the range to be checked * @return {@code true} if the specified range of the array is sorted in ascending order, {@code false} otherwise * @throws IndexOutOfBoundsException if the specified range is out of bounds */ public static boolean isSorted(final short[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); if (toIndex - fromIndex < 2) { return true; } else if (a[toIndex - 1] < a[fromIndex]) { return false; } for (int i = fromIndex + 1; i < toIndex; i++) { if (a[i] < a[i - 1]) { return false; } } return true; } /** * Checks if the specified integer array is sorted in ascending order. * * @param a the integer array to be checked * @return {@code true} if the array is sorted in ascending order, {@code false} otherwise */ public static boolean isSorted(final int[] a) { final int len = len(a); if (len < 2) { return true; } else if (a[len - 1] < a[0]) { return false; } for (int i = 1; i < len; i++) { if (a[i] < a[i - 1]) { return false; } } return true; } /** * Checks if the specified range of the integer array is sorted in ascending order. * * @param a the array to be checked * @param fromIndex the starting index (inclusive) of the range to be checked * @param toIndex the ending index (exclusive) of the range to be checked * @return {@code true} if the specified range of the array is sorted in ascending order, {@code false} otherwise * @throws IndexOutOfBoundsException if the specified range is out of bounds */ public static boolean isSorted(final int[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); if (toIndex - fromIndex < 2) { return true; } else if (a[toIndex - 1] < a[fromIndex]) { return false; } for (int i = fromIndex + 1; i < toIndex; i++) { if (a[i] < a[i - 1]) { return false; } } return true; } /** * Checks if the specified long array is sorted in ascending order. * * @param a the long array to be checked * @return {@code true} if the array is sorted in ascending order, {@code false} otherwise */ public static boolean isSorted(final long[] a) { final int len = len(a); if (len < 2) { return true; } else if (a[len - 1] < a[0]) { return false; } for (int i = 1; i < len; i++) { if (a[i] < a[i - 1]) { return false; } } return true; } /** * Checks if the specified range of the long array is sorted in ascending order. * * @param a the array to be checked * @param fromIndex the starting index (inclusive) of the range to be checked * @param toIndex the ending index (exclusive) of the range to be checked * @return {@code true} if the specified range of the array is sorted in ascending order, {@code false} otherwise * @throws IndexOutOfBoundsException if the specified range is out of bounds */ public static boolean isSorted(final long[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); if (toIndex - fromIndex < 2) { return true; } else if (a[toIndex - 1] < a[fromIndex]) { return false; } for (int i = fromIndex + 1; i < toIndex; i++) { if (a[i] < a[i - 1]) { return false; } } return true; } /** * Checks if the specified float array is sorted in ascending order. * * @param a the float array to be checked * @return {@code true} if the array is sorted in ascending order, {@code false} otherwise */ public static boolean isSorted(final float[] a) { final int len = len(a); if (len < 2) { return true; } else if (Float.compare(a[len - 1], a[0]) < 0) { return false; } for (int i = 1; i < len; i++) { if (Float.compare(a[i], a[i - 1]) < 0) { return false; } } return true; } /** * Checks if the specified range of the float array is sorted in ascending order. * * @param a the array to be checked * @param fromIndex the starting index (inclusive) of the range to be checked * @param toIndex the ending index (exclusive) of the range to be checked * @return {@code true} if the specified range of the array is sorted in ascending order, {@code false} otherwise * @throws IndexOutOfBoundsException if the specified range is out of bounds */ public static boolean isSorted(final float[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); if (toIndex - fromIndex < 2) { return true; } else if (Float.compare(a[toIndex - 1], a[fromIndex]) < 0) { return false; } for (int i = fromIndex + 1; i < toIndex; i++) { if (Float.compare(a[i], a[i - 1]) < 0) { return false; } } return true; } /** * Checks if the specified double array is sorted in ascending order. * * @param a the double array to be checked * @return {@code true} if the array is sorted in ascending order, {@code false} otherwise */ public static boolean isSorted(final double[] a) { final int len = len(a); if (len < 2) { return true; } else if (Double.compare(a[len - 1], a[0]) < 0) { return false; } for (int i = 1; i < len; i++) { if (Double.compare(a[i], a[i - 1]) < 0) { return false; } } return true; } /** * Checks if the specified range of the double array is sorted in ascending order. * * @param a the array to be checked * @param fromIndex the starting index (inclusive) of the range to be checked * @param toIndex the ending index (exclusive) of the range to be checked * @return {@code true} if the specified range of the array is sorted in ascending order, {@code false} otherwise * @throws IndexOutOfBoundsException if the specified range is out of bounds */ public static boolean isSorted(final double[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); if (toIndex - fromIndex < 2) { return true; } else if (Double.compare(a[toIndex - 1], a[fromIndex]) < 0) { return false; } for (int i = fromIndex + 1; i < toIndex; i++) { if (Double.compare(a[i], a[i - 1]) < 0) { return false; } } return true; } /** * Checks if the specified array is sorted in ascending order (where {@code null} is smallest). * * @param the type of elements in the array, which must be Comparable * @param a the array to be checked * @return {@code true} if the array is sorted in ascending order, {@code false} otherwise * @see Comparators#naturalOrder() * @see Comparators#nullsFirst() * @see Comparators#nullsLast() * @see Comparators#comparingBy(Function) */ public static > boolean isSorted(final T[] a) { final int len = len(a); if (len < 2) { return true; } else if (compare(a[len - 1], a[0]) < 0) { return false; } for (int i = 1; i < len; i++) { if (compare(a[i], a[i - 1]) < 0) { return false; } } return true; } /** * Checks if the specified range of the array is sorted in ascending order (where {@code null} is smallest). * * @param the type of elements in the array, which must be Comparable * @param a the array to be checked * @param fromIndex the starting index (inclusive) of the range to be checked * @param toIndex the ending index (exclusive) of the range to be checked * @return {@code true} if the specified range of the array is sorted in ascending order, {@code false} otherwise * @throws IndexOutOfBoundsException if the specified range is out of bounds * @see Comparators#naturalOrder() * @see Comparators#nullsFirst() * @see Comparators#nullsLast() * @see Comparators#comparingBy(Function) */ public static > boolean isSorted(final T[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); if (toIndex - fromIndex < 2) { return true; } else if (compare(a[toIndex - 1], a[fromIndex]) < 0) { return false; } for (int i = fromIndex + 1; i < toIndex; i++) { if (compare(a[i], a[i - 1]) < 0) { return false; } } return true; } /** * Checks if the array is sorted according to the order induced by the specified comparator. * * @param the type of elements in the array * @param a the array to be checked * @param cmp the comparator to determine the order of the array * @return {@code true} if the array is sorted according to the specified comparator, {@code false} otherwise * @see Comparators#naturalOrder() * @see Comparators#nullsFirst() * @see Comparators#nullsLast() * @see Comparators#comparingBy(Function) */ public static boolean isSorted(final T[] a, Comparator cmp) { cmp = checkComparator(cmp); final int len = len(a); if (len < 2) { return true; } else if (cmp.compare(a[len - 1], a[0]) < 0) { return false; } for (int i = 1; i < len; i++) { if (cmp.compare(a[i], a[i - 1]) < 0) { return false; } } return true; } /** * Checks if the specified range of the array is sorted according to the order induced by the specified comparator. * * @param the type of elements in the array * @param a the array to be checked * @param fromIndex the starting index (inclusive) of the range to be checked * @param toIndex the ending index (exclusive) of the range to be checked * @param cmp the comparator to determine the order of the array * @return {@code true} if the specified range of the array is sorted according to the specified comparator, {@code false} otherwise * @throws IndexOutOfBoundsException if the specified range is out of bounds * @see Comparators#naturalOrder() * @see Comparators#nullsFirst() * @see Comparators#nullsLast() * @see Comparators#comparingBy(Function) */ public static boolean isSorted(final T[] a, final int fromIndex, final int toIndex, Comparator cmp) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); cmp = checkComparator(cmp); if (toIndex - fromIndex < 2) { return true; } else if (cmp.compare(a[toIndex - 1], a[fromIndex]) < 0) { return false; } for (int i = fromIndex + 1; i < toIndex; i++) { if (cmp.compare(a[i], a[i - 1]) < 0) { return false; } } return true; } /** * Checks if the collection is sorted in ascending order (where {@code null} is smallest). * * @param the type of elements in the collection * @param c the collection to be checked * @return {@code true} if the collection is sorted in natural order, {@code false} otherwise * @see Comparators#naturalOrder() * @see Comparators#nullsFirst() * @see Comparators#nullsLast() * @see Comparators#comparingBy(Function) */ public static > boolean isSorted(final Collection c) { if (size(c) < 2) { return true; } final Iterator iter = c.iterator(); T prev = iter.next(); T cur = null; while (iter.hasNext()) { cur = iter.next(); if (compare(cur, prev) < 0) { return false; } prev = cur; } return true; } /** * Checks if the specified range of the collection is sorted in ascending order (where {@code null} is smallest). * * @param the type of elements in the collection * @param c the collection to be checked * @param fromIndex the starting index (inclusive) of the range to be checked * @param toIndex the ending index (exclusive) of the range to be checked * @return {@code true} if the specified range of the collection is sorted in natural order, {@code false} otherwise * @throws IndexOutOfBoundsException if the specified range is out of bounds * @see Comparators#naturalOrder() * @see Comparators#nullsFirst() * @see Comparators#nullsLast() * @see Comparators#comparingBy(Function) */ public static > boolean isSorted(final Collection c, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, size(c)); if (toIndex - fromIndex < 2) { return true; } final Iterator iter = c.iterator(); int cursor = 0; while (cursor < fromIndex) { iter.next(); cursor++; } cursor++; T prev = iter.next(); T cur = null; while (cursor < toIndex) { cur = iter.next(); if (compare(cur, prev) < 0) { return false; } prev = cur; cursor++; } return true; } /** * Checks if the collection is sorted according to the order induced by the specified comparator. * * @param the type of elements in the collection * @param c the collection to be checked * @param cmp the comparator to determine the order of the collection * @return {@code true} if the collection is sorted according to the specified comparator, {@code false} otherwise * @see Comparators#naturalOrder() * @see Comparators#nullsFirst() * @see Comparators#nullsLast() * @see Comparators#comparingBy(Function) */ public static boolean isSorted(final Collection c, Comparator cmp) { if (size(c) < 2) { return true; } cmp = checkComparator(cmp); final Iterator iter = c.iterator(); T prev = iter.next(); T cur = null; while (iter.hasNext()) { cur = iter.next(); if (cmp.compare(cur, prev) < 0) { return false; } prev = cur; } return true; } /** * Checks if the specified range of the collection is sorted according to the order induced by the specified comparator. * * @param the type of elements in the collection * @param c the collection to be checked * @param fromIndex the starting index (inclusive) of the range to be checked * @param toIndex the ending index (exclusive) of the range to be checked * @param cmp the comparator to determine the order of the collection * @return {@code true} if the specified range of the collection is sorted according to the specified comparator, {@code false} otherwise * @throws IndexOutOfBoundsException if the specified range is out of bounds * @see Comparators#naturalOrder() * @see Comparators#nullsFirst() * @see Comparators#nullsLast() * @see Comparators#comparingBy(Function) */ public static boolean isSorted(final Collection c, final int fromIndex, final int toIndex, Comparator cmp) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, size(c)); if (toIndex - fromIndex < 2) { return true; } cmp = checkComparator(cmp); final Iterator iter = c.iterator(); int cursor = 0; while (cursor < fromIndex) { iter.next(); cursor++; } cursor++; T prev = iter.next(); T cur = null; while (cursor < toIndex) { cur = iter.next(); if (cmp.compare(cur, prev) < 0) { return false; } prev = cur; cursor++; } return true; } /** * Sorts the specified array of booleans into ascending order. {@code false} is considered less than {@code true}. * * @param a the array to be sorted */ public static void sort(final boolean[] a) { if (isEmpty(a)) { return; } sort(a, 0, a.length); } /** * Sorts the specified range of the array into ascending order. {@code false} is considered less than {@code true}. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws ArrayIndexOutOfBoundsException if fromIndex or toIndex is out of range */ public static void sort(final boolean[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a) || fromIndex == toIndex) { return; } int numOfFalse = 0; for (int i = fromIndex; i < toIndex; i++) { if (!a[i]) { numOfFalse++; } } fill(a, fromIndex, numOfFalse, false); fill(a, fromIndex + numOfFalse, toIndex, true); } /** * Sorts the specified array into ascending order. * * @param a the array to be sorted */ public static void sort(final char[] a) { if (isEmpty(a)) { return; } Arrays.sort(a); } /** * Sorts the specified range of the array into ascending order. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws ArrayIndexOutOfBoundsException if fromIndex or toIndex is out of range */ public static void sort(final char[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a) || fromIndex == toIndex) { return; } Arrays.sort(a, fromIndex, toIndex); } /** * Sorts the specified array into ascending numerical order. * * @param a the array to be sorted */ public static void sort(final byte[] a) { if (isEmpty(a)) { return; } Arrays.sort(a); } /** * Sorts the specified range of the array into ascending order. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws ArrayIndexOutOfBoundsException if fromIndex or toIndex is out of range */ public static void sort(final byte[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a) || fromIndex == toIndex) { return; } Arrays.sort(a, fromIndex, toIndex); } /** * Sorts the specified array into ascending numerical order. * * @param a the array to be sorted */ public static void sort(final short[] a) { if (isEmpty(a)) { return; } Arrays.sort(a); } /** * Sorts the specified range of the array into ascending order. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws ArrayIndexOutOfBoundsException if fromIndex or toIndex is out of range */ public static void sort(final short[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a) || fromIndex == toIndex) { return; } Arrays.sort(a, fromIndex, toIndex); } /** * Sorts the specified array into ascending numerical order. * * @param a the array to be sorted */ public static void sort(final int[] a) { if (isEmpty(a)) { return; } Arrays.sort(a); } /** * Sorts the specified range of the array into ascending order. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws ArrayIndexOutOfBoundsException if fromIndex or toIndex is out of range */ public static void sort(final int[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a) || fromIndex == toIndex) { return; } Arrays.sort(a, fromIndex, toIndex); } /** * Sorts the specified array into ascending numerical order. * * @param a the array to be sorted */ public static void sort(final long[] a) { if (isEmpty(a)) { return; } Arrays.sort(a); } /** * Sorts the specified range of the array into ascending order. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws ArrayIndexOutOfBoundsException if fromIndex or toIndex is out of range */ public static void sort(final long[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a) || fromIndex == toIndex) { return; } Arrays.sort(a, fromIndex, toIndex); } /** * Sorts the specified array into ascending numerical order. * * @param a the array to be sorted */ public static void sort(final float[] a) { if (isEmpty(a)) { return; } Arrays.sort(a); } /** * Sorts the specified range of the array into ascending order. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws ArrayIndexOutOfBoundsException if fromIndex or toIndex is out of range */ public static void sort(final float[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a) || fromIndex == toIndex) { return; } Arrays.sort(a, fromIndex, toIndex); } /** * Sorts the specified array into ascending order. * * @param a the array to be sorted */ public static void sort(final double[] a) { if (isEmpty(a)) { return; } Arrays.sort(a); } /** * Sorts the specified range of the array into ascending order. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws ArrayIndexOutOfBoundsException if fromIndex or toIndex is out of range */ public static void sort(final double[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a) || fromIndex == toIndex) { return; } Arrays.sort(a, fromIndex, toIndex); } /** * Sorts the specified array according to the natural ordering (where {@code null} is smallest). * * @param a the array to be sorted * @throws ClassCastException if the array contains elements that are not mutually comparable * @see Arrays#sort(Object[]) * @see Arrays#sort(Object[], Comparator) * @see Arrays#sort(Object[], int, int, Comparator) * @see Comparators#naturalOrder() * @see Comparators#nullsFirst() * @see Comparators#nullsLast() * @see Comparators#comparingBy(Function) */ public static void sort(final Object[] a) { if (isEmpty(a)) { return; } sort(a, NATURAL_COMPARATOR); } /** * Sorts the specified range of the specified array according to the natural ordering (where {@code null} is smallest). * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws ArrayIndexOutOfBoundsException if fromIndex or toIndex is out of range * @see Arrays#sort(Object[]) * @see Arrays#sort(Object[], Comparator) * @see Arrays#sort(Object[], int, int, Comparator) * @see Comparators#naturalOrder() * @see Comparators#nullsFirst() * @see Comparators#nullsLast() * @see Comparators#comparingBy(Function) */ public static void sort(final Object[] a, final int fromIndex, final int toIndex) { sort(a, fromIndex, toIndex, NATURAL_COMPARATOR); } /** * Sorts the specified array according to the order induced by the specified comparator. * * @param the type of the objects being compared * @param a the array to be sorted * @param cmp the comparator to determine the order of the array. A {@code null} value indicates that the elements' natural ordering should be used. * @see Arrays#sort(Object[]) * @see Arrays#sort(Object[], Comparator) * @see Arrays#sort(Object[], int, int, Comparator) * @see Comparators#naturalOrder() * @see Comparators#nullsFirst() * @see Comparators#nullsLast() * @see Comparators#comparingBy(Function) */ public static void sort(final T[] a, final Comparator cmp) { if (isEmpty(a)) { return; } sort(a, 0, a.length, cmp); } /** * Sorts the specified range of the specified array according to the order induced by the specified comparator. * * @param the type of the objects being compared * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @param cmp the comparator to determine the order of the array. A {@code null} value indicates that the elements' natural ordering should be used. * @throws IndexOutOfBoundsException if the specified range is out of bounds * @see Arrays#sort(Object[]) * @see Arrays#sort(Object[], Comparator) * @see Arrays#sort(Object[], int, int, Comparator) * @see Comparators#naturalOrder() * @see Comparators#nullsFirst() * @see Comparators#nullsLast() * @see Comparators#comparingBy(Function) */ public static void sort(final T[] a, final int fromIndex, final int toIndex, final Comparator cmp) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a) || fromIndex == toIndex) { return; } Arrays.sort(a, fromIndex, toIndex, cmp); } /** * Sorts the specified list according to the natural ordering (where {@code null} is smallest). * * @param the type of the elements in the list * @param list the list to be sorted * @see Arrays#sort(Object[]) * @see Arrays#sort(Object[], Comparator) * @see Arrays#sort(Object[], int, int, Comparator) * @see Comparators#naturalOrder() * @see Comparators#nullsFirst() * @see Comparators#nullsLast() * @see Comparators#comparingBy(Function) */ public static > void sort(final List list) { if (isEmpty(list)) { return; } sort(list, 0, list.size(), NATURAL_COMPARATOR); } /** * Sorts the specified range of the specified list according to the natural ordering (where {@code null} is smallest). * * @param the type of the elements in the list * @param list the list to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws IndexOutOfBoundsException if the specified range is out of * @see Arrays#sort(Object[]) * @see Arrays#sort(Object[], Comparator) * @see Arrays#sort(Object[], int, int, Comparator) * @see Comparators#naturalOrder() * @see Comparators#nullsFirst() * @see Comparators#nullsLast() * @see Comparators#comparingBy(Function) */ public static > void sort(final List list, final int fromIndex, final int toIndex) { if (isEmpty(list)) { return; } sort(list, fromIndex, toIndex, NATURAL_COMPARATOR); } /** * Sorts the specified list according to the order induced by the specified comparator. * * @param the type of the elements in the list * @param list the list to be sorted * @param cmp the comparator to determine the order of the list. A {@code null} value indicates that the elements' natural ordering should be used * @see Arrays#sort(Object[]) * @see Arrays#sort(Object[], Comparator) * @see Arrays#sort(Object[], int, int, Comparator) * @see Comparators#naturalOrder() * @see Comparators#nullsFirst() * @see Comparators#nullsLast() * @see Comparators#comparingBy(Function) */ public static void sort(final List list, final Comparator cmp) { if (isEmpty(list)) { return; } sort(list, 0, list.size(), cmp); } /** * Sorts the specified range of the list according to the order induced by the specified comparator. * * @param the type of the elements in the list * @param list the list to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @param cmp the comparator to determine the order of the list. A {@code null} value indicates that the elements' natural ordering should be used. * @throws IndexOutOfBoundsException if the specified range is out of bounds * @see Arrays#sort(Object[]) * @see Arrays#sort(Object[], Comparator) * @see Arrays#sort(Object[], int, int, Comparator) * @see Comparators#naturalOrder() * @see Comparators#nullsFirst() * @see Comparators#nullsLast() * @see Comparators#comparingBy(Function) */ public static void sort(final List list, final int fromIndex, final int toIndex, final Comparator cmp) { if ((isEmpty(list) && fromIndex == 0 && toIndex == 0) || fromIndex == toIndex) { return; } if (fromIndex == 0 && toIndex == list.size()) { list.sort(cmp); return; } @SuppressWarnings("deprecation") final T[] a = (T[]) InternalUtil.getInternalArray(list); if (a != null) { sort(a, fromIndex, toIndex, cmp); return; } final T[] array = (T[]) list.toArray(); Arrays.sort(array, fromIndex, toIndex, cmp); final ListIterator i = (ListIterator) list.listIterator(); for (final T element : array) { i.next(); i.set(element); } } /** * Sorts the specified array based on the keys extracted by the provided {@code Function}. * * @param the type of elements in the array * @param the type of the key values, which must be comparable * @param a the array to be sorted * @param keyExtractor the function to extract the key values from the array elements * @see Comparators#comparingBy(Function) * @see Comparators#comparingByIfNotNullOrElseNullsFirst(Function) * @see Comparators#comparingByIfNotNullOrElseNullsLast(Function) */ public static > void sortBy(final T[] a, final Function keyExtractor) { sort(a, Comparators.comparingBy(keyExtractor)); } /** * Sorts the specified list based on the keys extracted by the provided {@code Function}. * * @param the type of elements in the list * @param the type of the key values, which must be comparable * @param list the List to be sorted * @param keyExtractor the function to extract the key values from the list elements * @see Comparators#comparingBy(Function) * @see Comparators#comparingByIfNotNullOrElseNullsFirst(Function) * @see Comparators#comparingByIfNotNullOrElseNullsLast(Function) */ public static > void sortBy(final List list, final Function keyExtractor) { sort(list, Comparators.comparingBy(keyExtractor)); } /** * Sorts the specified array into ascending numerical order based on the keys extracted by the provided {@code ToIntFunction}. * * @param the type of elements in the array * @param a the array to be sorted * @param keyExtractor the function to extract the key values from the array elements */ public static void sortByInt(final T[] a, final ToIntFunction keyExtractor) { sort(a, Comparators.comparingInt(keyExtractor)); } /** * Sorts the specified list into ascending numerical order based on the keys extracted by the provided {@code ToIntFunction}. * * @param the type of elements in the list * @param list the list to be sorted * @param keyExtractor the function to extract the key values from the list elements */ public static void sortByInt(final List list, final ToIntFunction keyExtractor) { sort(list, Comparators.comparingInt(keyExtractor)); } /** * Sorts the specified array into ascending numerical order based on the keys extracted by the provided {@code ToLongFunction}. * * @param the type of elements in the array * @param a the array to be sorted * @param keyExtractor the function to extract the key values from the array elements */ public static void sortByLong(final T[] a, final ToLongFunction keyExtractor) { sort(a, Comparators.comparingLong(keyExtractor)); } /** * Sorts the specified list into ascending numerical order based on the keys extracted by the provided {@code ToLongFunction}. * * @param the type of elements in the list * @param list the list to be sorted * @param keyExtractor the function to extract the key values from the list elements */ public static void sortByLong(final List list, final ToLongFunction keyExtractor) { sort(list, Comparators.comparingLong(keyExtractor)); } /** * Sorts the specified array into ascending numerical order based on the keys extracted by the provided {@code ToFloatFunction}. * * @param the type of elements in the array * @param a the array to be sorted * @param keyExtractor the function to extract the key values from the array elements */ public static void sortByFloat(final T[] a, final ToFloatFunction keyExtractor) { sort(a, Comparators.comparingFloat(keyExtractor)); } /** * Sorts the specified list into ascending numerical order based on the keys extracted by the provided {@code ToFloatFunction}. * * @param the type of elements in the list * @param list the list to be sorted * @param keyExtractor the function to extract the key values from the list elements */ public static void sortByFloat(final List list, final ToFloatFunction keyExtractor) { sort(list, Comparators.comparingFloat(keyExtractor)); } /** * Sorts the specified array into ascending numerical order based on the keys extracted by the provided {@code ToDoubleFunction}. * * @param the type of elements in the array * @param a the array to be sorted * @param keyExtractor the function to extract the key values from the array elements */ public static void sortByDouble(final T[] a, final ToDoubleFunction keyExtractor) { sort(a, Comparators.comparingDouble(keyExtractor)); } /** * Sorts the specified list into ascending numerical order based on the keys extracted by the provided {@code ToDoubleFunction}. * * @param the type of elements in the list * @param list the list to be sorted * @param keyExtractor the function to extract the key values from the list elements */ public static void sortByDouble(final List list, final ToDoubleFunction keyExtractor) { sort(list, Comparators.comparingDouble(keyExtractor)); } /* * Tested by ArrayUtilTest.test_parallel_sort_perf @Test public void test_parallel_sort_perf() { final int arrayLength = 3000; final int loopNum = 100000; { final int[] a = Array.random(arrayLength); Profiler.run(1, loopNum, 3, "Arrays.sort(int[])", () -> Arrays.sort(a.clone())).printResult(); Profiler.run(1, loopNum, 3, "sort(int[])", () -> sort(a.clone())).printResult(); Profiler.run(1, loopNum, 3, "Arrays.parallelSort(int[])", () -> Arrays.parallelSort(a.clone())).printResult(); Profiler.run(1, loopNum, 3, "parallelSort(int[])", () -> parallelSort(a.clone())).printResult(); } { final long[] a = LongList.random(arrayLength).toArray(); Profiler.run(1, loopNum, 3, "Arrays.sort(long[])", () -> Arrays.sort(a.clone())).printResult(); Profiler.run(1, loopNum, 3, "sort(long[])", () -> sort(a.clone())).printResult(); Profiler.run(1, loopNum, 3, "Arrays.parallelSort(long[])", () -> Arrays.parallelSort(a.clone())).printResult(); Profiler.run(1, loopNum, 3, "parallelSort(long[])", () -> parallelSort(a.clone())).printResult(); } { final double[] a = DoubleList.random(arrayLength).toArray(); Profiler.run(1, loopNum, 3, "Arrays.sort(double[])", () -> Arrays.sort(a.clone())).printResult(); Profiler.run(1, loopNum, 3, "sort(double[])", () -> sort(a.clone())).printResult(); Profiler.run(1, loopNum, 3, "Arrays.parallelSort(double[])", () -> Arrays.parallelSort(a.clone())).printResult(); Profiler.run(1, loopNum, 3, "parallelSort(double[])", () -> parallelSort(a.clone())).printResult(); } { final String[] a = new String[2000]; for (int i = 0; i < a.length; i++) { a[i] = Strings.uuid(); } Profiler.run(1, loopNum, 3, "Arrays.sort(Object[])", () -> Arrays.sort(a.clone())).printResult(); Profiler.run(1, loopNum, 3, "sort(Object[])", () -> sort(a.clone())).printResult(); Profiler.run(1, loopNum, 3, "Arrays.parallelSort(Object[])", () -> Arrays.parallelSort(a.clone())).printResult(); Profiler.run(1, loopNum, 3, "parallelSort(Object[])", () -> parallelSort(a.clone())).printResult(); } } */ private static final int PARALLEL_SORT_PRIMITIVE_THRESHOLD = 3000; private static final int PARALLEL_SORT_OBJECT_THRESHOLD = 2000; /** * Sorts the specified array into ascending numerical order by multiple threads. * * @param a the array to be sorted * @see Arrays#parallelSort(char[]) * @see Arrays#parallelSort(char[], int, int) */ public static void parallelSort(final char[] a) { if (isEmpty(a)) { return; } parallelSort(a, 0, a.length); } /** * Sorts the specified range of the array into ascending numerical order by multiple threads. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws IndexOutOfBoundsException if the fromIndex or toIndex is out of range * @see Arrays#parallelSort(char[]) * @see Arrays#parallelSort(char[], int, int) */ public static void parallelSort(final char[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a) || fromIndex == toIndex) { return; } if (toIndex - fromIndex <= PARALLEL_SORT_PRIMITIVE_THRESHOLD || IOUtil.CPU_CORES == 1) { Arrays.sort(a, fromIndex, toIndex); } else { Arrays.parallelSort(a, fromIndex, toIndex); } } /** * Sorts the specified array into ascending numerical order by multiple threads. * * @param a the array to be sorted * @see Arrays#parallelSort(byte[]) * @see Arrays#parallelSort(byte[], int, int) */ public static void parallelSort(final byte[] a) { if (isEmpty(a)) { return; } parallelSort(a, 0, a.length); } /** * Sorts the specified range of the array into ascending numerical order by multiple threads. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws IndexOutOfBoundsException if the fromIndex or toIndex is out of range * @see Arrays#parallelSort(byte[]) * @see Arrays#parallelSort(byte[], int, int) */ public static void parallelSort(final byte[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a) || fromIndex == toIndex) { return; } if (toIndex - fromIndex <= PARALLEL_SORT_PRIMITIVE_THRESHOLD || IOUtil.CPU_CORES == 1) { Arrays.sort(a, fromIndex, toIndex); } else { Arrays.parallelSort(a, fromIndex, toIndex); } } /** * Sorts the specified array into ascending numerical order by multiple threads. * * @param a the array to be sorted * @see Arrays#parallelSort(short[]) * @see Arrays#parallelSort(short[], int, int) */ public static void parallelSort(final short[] a) { if (isEmpty(a)) { return; } parallelSort(a, 0, a.length); } /** * Sorts the specified range of the array into ascending numerical order by multiple threads. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws IndexOutOfBoundsException if the fromIndex or toIndex is out of range * @see Arrays#parallelSort(short[]) * @see Arrays#parallelSort(short[], int, int) */ public static void parallelSort(final short[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a) || fromIndex == toIndex) { return; } if (toIndex - fromIndex <= PARALLEL_SORT_PRIMITIVE_THRESHOLD || IOUtil.CPU_CORES == 1) { Arrays.sort(a, fromIndex, toIndex); } else { Arrays.parallelSort(a, fromIndex, toIndex); } } /** * Sorts the specified array into ascending numerical order by multiple threads. * * @param a the array to be sorted * @see Arrays#parallelSort(int[]) * @see Arrays#parallelSort(int[], int, int) */ public static void parallelSort(final int[] a) { if (isEmpty(a)) { return; } parallelSort(a, 0, a.length); } /** * Sorts the specified range of the array into ascending numerical order by multiple threads. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws IndexOutOfBoundsException if the fromIndex or toIndex is out of range * @see Arrays#parallelSort(int[]) * @see Arrays#parallelSort(int[], int, int) */ public static void parallelSort(final int[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a) || fromIndex == toIndex) { return; } if (toIndex - fromIndex <= PARALLEL_SORT_PRIMITIVE_THRESHOLD || IOUtil.CPU_CORES == 1) { Arrays.sort(a, fromIndex, toIndex); } else { Arrays.parallelSort(a, fromIndex, toIndex); } } /** * Sorts the specified array into ascending numerical order by multiple threads. * * @param a the array to be sorted * @see Arrays#parallelSort(long[]) * @see Arrays#parallelSort(long[], int, int) */ public static void parallelSort(final long[] a) { if (isEmpty(a)) { return; } parallelSort(a, 0, a.length); } /** * Sorts the specified range of the array into ascending numerical order by multiple threads. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws IndexOutOfBoundsException if the fromIndex or toIndex is out of range * @see Arrays#parallelSort(long[]) * @see Arrays#parallelSort(long[], int, int) */ public static void parallelSort(final long[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a) || fromIndex == toIndex) { return; } if (toIndex - fromIndex <= PARALLEL_SORT_PRIMITIVE_THRESHOLD || IOUtil.CPU_CORES == 1) { Arrays.sort(a, fromIndex, toIndex); } else { Arrays.parallelSort(a, fromIndex, toIndex); } } /** * Sorts the specified array into ascending numerical order by multiple threads. * * @param a the array to be sorted * @see Arrays#parallelSort(float[]) * @see Arrays#parallelSort(float[], int, int) */ public static void parallelSort(final float[] a) { if (isEmpty(a)) { return; } parallelSort(a, 0, a.length); } /** * Sorts the specified range of the array into ascending numerical order by multiple threads. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws IndexOutOfBoundsException if the fromIndex or toIndex is out of range * @see Arrays#parallelSort(float[]) * @see Arrays#parallelSort(float[], int, int) */ public static void parallelSort(final float[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a) || fromIndex == toIndex) { return; } if (toIndex - fromIndex <= PARALLEL_SORT_PRIMITIVE_THRESHOLD || IOUtil.CPU_CORES == 1) { Arrays.sort(a, fromIndex, toIndex); } else { Arrays.parallelSort(a, fromIndex, toIndex); } } /** * Sorts the specified array into ascending numerical order by multiple threads. * * @param a the array to be sorted * @see Arrays#parallelSort(double[]) * @see Arrays#parallelSort(double[], int, int) */ public static void parallelSort(final double[] a) { if (isEmpty(a)) { return; } parallelSort(a, 0, a.length); } /** * Sorts the specified range of the array into ascending numerical order by multiple threads. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws IndexOutOfBoundsException if the fromIndex or toIndex is out of range * @see Arrays#parallelSort(double[]) * @see Arrays#parallelSort(double[], int, int) */ public static void parallelSort(final double[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a) || fromIndex == toIndex) { return; } if (toIndex - fromIndex <= PARALLEL_SORT_PRIMITIVE_THRESHOLD || IOUtil.CPU_CORES == 1) { Arrays.sort(a, fromIndex, toIndex); } else { Arrays.parallelSort(a, fromIndex, toIndex); } } /** * Sorts the specified array according to the natural ordering (where {@code null} is minimum) by multiple threads. * * @param the type of the elements in the array * @param a the array to be sorted * @see Arrays#parallelSort(Comparable[]) * @see Arrays#parallelSort(Object[], Comparator) * @see Arrays#parallelSort(Object[], int, int, Comparator) * @see Comparators#naturalOrder() * @see Comparators#nullsFirst() * @see Comparators#nullsLast() * @see Comparators#comparingBy(Function) */ public static > void parallelSort(final T[] a) { if (isEmpty(a)) { return; } parallelSort(a, 0, a.length); } /** * Sorts the specified range of the specified array according to the natural ordering (where {@code null} is minimum) by multiple threads. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws IllegalArgumentException if fromIndex > toIndex * @throws ArrayIndexOutOfBoundsException if fromIndex or toIndex is out of range * @see Arrays#parallelSort(Comparable[]) * @see Arrays#parallelSort(Object[], Comparator) * @see Arrays#parallelSort(Object[], int, int, Comparator) * @see Comparators#naturalOrder() * @see Comparators#nullsFirst() * @see Comparators#nullsLast() * @see Comparators#comparingBy(Function) */ public static > void parallelSort(final T[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a) || fromIndex == toIndex) { return; } parallelSort(a, fromIndex, toIndex, NATURAL_COMPARATOR); } /** * Sorts the specified array according to the order induced by the specified comparator by multiple threads. * * @param the type of the objects being compared * @param a the array to be sorted * @param cmp the comparator to determine the order of the array. A {@code null} value indicates that the elements' natural ordering should be used. * @see Arrays#parallelSort(Comparable[]) * @see Arrays#parallelSort(Object[], Comparator) * @see Arrays#parallelSort(Object[], int, int, Comparator) * @see Comparators#naturalOrder() * @see Comparators#nullsFirst() * @see Comparators#nullsLast() * @see Comparators#comparingBy(Function) */ public static void parallelSort(final T[] a, final Comparator cmp) { if (isEmpty(a)) { return; } parallelSort(a, 0, a.length, cmp); } /** * Sorts the specified range of the specified array according to the order induced by the specified comparator by multiple threads. * * @param the type of the objects being compared * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @param cmp the comparator to determine the order of the array. A {@code null} value indicates that the elements' natural ordering should be used. * @throws IndexOutOfBoundsException if the specified range is out of bounds * @see Arrays#parallelSort(Comparable[]) * @see Arrays#parallelSort(Object[], Comparator) * @see Arrays#parallelSort(Object[], int, int, Comparator) * @see Comparators#naturalOrder() * @see Comparators#nullsFirst() * @see Comparators#nullsLast() * @see Comparators#comparingBy(Function) */ public static void parallelSort(final T[] a, final int fromIndex, final int toIndex, final Comparator cmp) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a) || fromIndex == toIndex) { return; } if (toIndex - fromIndex <= PARALLEL_SORT_OBJECT_THRESHOLD || IOUtil.CPU_CORES == 1) { Arrays.sort(a, fromIndex, toIndex, cmp); } else { Arrays.parallelSort(a, fromIndex, toIndex, cmp); } } /** * Sorts the specified list according to the natural ordering (where {@code null} is minimum) by multiple threads. * * @param the type of the elements in the list * @param list the list to be sorted * @see Arrays#parallelSort(Comparable[]) * @see Arrays#parallelSort(Object[], Comparator) * @see Arrays#parallelSort(Object[], int, int, Comparator) * @see Comparators#naturalOrder() * @see Comparators#nullsFirst() * @see Comparators#nullsLast() * @see Comparators#comparingBy(Function) */ public static > void parallelSort(final List list) { if (isEmpty(list)) { return; } parallelSort(list, 0, list.size()); } /** * Sorts the specified range of the specified list according to the natural ordering (where {@code null} is minimum) by multiple threads. * * @param the type of the elements in the list * @param list the list to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws IndexOutOfBoundsException if the specified range is out of * @see Arrays#parallelSort(Comparable[]) * @see Arrays#parallelSort(Object[], Comparator) * @see Arrays#parallelSort(Object[], int, int, Comparator) * @see Comparators#naturalOrder() * @see Comparators#nullsFirst() * @see Comparators#nullsLast() * @see Comparators#comparingBy(Function) */ public static > void parallelSort(final List list, final int fromIndex, final int toIndex) { parallelSort(list, fromIndex, toIndex, NATURAL_COMPARATOR); } /** * Sorts the specified list according to the order induced by the specified comparator by multiple threads. * * @param the type of the elements in the list * @param list the list to be sorted * @param cmp the comparator to determine the order of the list. A {@code null} value indicates that the elements' natural ordering should be used * @see Arrays#parallelSort(Comparable[]) * @see Arrays#parallelSort(Object[], Comparator) * @see Arrays#parallelSort(Object[], int, int, Comparator) * @see Comparators#naturalOrder() * @see Comparators#nullsFirst() * @see Comparators#nullsLast() * @see Comparators#comparingBy(Function) */ public static void parallelSort(final List list, final Comparator cmp) { if (isEmpty(list)) { return; } parallelSort(list, 0, list.size(), cmp); } /** * Sorts the specified range of the list according to the order induced by the specified comparator by multiple threads. * * @param the type of the elements in the list * @param list the list to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @param cmp the comparator to determine the order of the list. A {@code null} value indicates that the elements' natural ordering should be used. * @throws IndexOutOfBoundsException if the specified range is out of bounds * @see Arrays#parallelSort(Comparable[]) * @see Arrays#parallelSort(Object[], Comparator) * @see Arrays#parallelSort(Object[], int, int, Comparator) * @see Comparators#naturalOrder() * @see Comparators#nullsFirst() * @see Comparators#nullsLast() * @see Comparators#comparingBy(Function) */ public static void parallelSort(final List list, final int fromIndex, final int toIndex, final Comparator cmp) { if ((isEmpty(list) && fromIndex == 0 && toIndex == 0) || fromIndex == toIndex) { return; } if ((fromIndex == 0 && toIndex == list.size()) && (toIndex - fromIndex <= PARALLEL_SORT_OBJECT_THRESHOLD || IOUtil.CPU_CORES == 1)) { list.sort(cmp); } else { @SuppressWarnings("deprecation") final T[] a = (T[]) InternalUtil.getInternalArray(list); if (a != null) { parallelSort(a, fromIndex, toIndex, cmp); return; } final T[] array = (T[]) list.toArray(); parallelSort(array, fromIndex, toIndex, cmp); final ListIterator it = (ListIterator) list.listIterator(); for (final T element : array) { it.next(); it.set(element); } } } /** * Sorts the specified array based on the keys extracted by the provided {@code Function} by multiple threads. * * @param the type of the elements in the array * @param the type of the keys extracted by the key extractor function * @param a the array to be sorted * @param keyExtractor the function used to extract the keys for comparison * @see Comparators#comparingBy(Function) * @see Comparators#comparingByIfNotNullOrElseNullsFirst(Function) * @see Comparators#comparingByIfNotNullOrElseNullsLast(Function) */ public static > void parallelSortBy(final T[] a, final Function keyExtractor) { parallelSort(a, Comparators.comparingBy(keyExtractor)); } /** * Sorts the specified list based on the keys extracted by the provided {@code Function} by multiple threads. * * @param the type of the elements in the list * @param the type of the keys extracted by the key extractor function * @param list the list to be sorted * @param keyExtractor the function used to extract the keys for comparison * @see Comparators#comparingBy(Function) * @see Comparators#comparingByIfNotNullOrElseNullsFirst(Function) * @see Comparators#comparingByIfNotNullOrElseNullsLast(Function) */ public static > void parallelSortBy(final List list, final Function keyExtractor) { parallelSort(list, Comparators.comparingBy(keyExtractor)); } /** * Sorts the specified array based on the int values extracted by the provided {@code ToIntFunction} by multiple threads. * * @param the type of the elements in the array * @param a the array to be sorted * @param keyExtractor the function used to extract the int key for comparison */ public static void parallelSortByInt(final T[] a, final ToIntFunction keyExtractor) { parallelSort(a, Comparators.comparingInt(keyExtractor)); } /** * Sorts the specified list based on the int values extracted by the provided {@code ToIntFunction} by multiple threads. * * @param the type of the elements in the list * @param list the list to be sorted * @param keyExtractor the function used to extract the int key for comparison */ public static void parallelSortByInt(final List list, final ToIntFunction keyExtractor) { parallelSort(list, Comparators.comparingInt(keyExtractor)); } /** * Sorts the specified array based on the long values extracted by the provided {@code ToLongFunction} by multiple threads. * * @param the type of the elements in the array * @param a the array to be sorted * @param keyExtractor the function used to extract the long key for comparison */ public static void parallelSortByLong(final T[] a, final ToLongFunction keyExtractor) { parallelSort(a, Comparators.comparingLong(keyExtractor)); } /** * Sorts the specified list based on the long values extracted by the provided {@code ToLongFunction} by multiple threads. * * @param the type of the elements in the list * @param list the list to be sorted * @param keyExtractor the function used to extract the long key for comparison */ public static void parallelSortByLong(final List list, final ToLongFunction keyExtractor) { parallelSort(list, Comparators.comparingLong(keyExtractor)); } /** * Sorts the specified array based on the float values extracted by the provided {@code ToFloatFunction} by multiple threads. * * @param the type of the elements in the array * @param a the array to be sorted * @param keyExtractor the function used to extract the float key for comparison */ public static void parallelSortByFloat(final T[] a, final ToFloatFunction keyExtractor) { parallelSort(a, Comparators.comparingFloat(keyExtractor)); } /** * Sorts the specified list based on the float values extracted by the provided {@code ToFloatFunction} by multiple threads. * * @param the type of the elements in the list * @param list the list to be sorted * @param keyExtractor the function used to extract the float key for comparison */ public static void parallelSortByFloat(final List list, final ToFloatFunction keyExtractor) { parallelSort(list, Comparators.comparingFloat(keyExtractor)); } /** * Sorts the specified array based on the double values extracted by the provided {@code ToDoubleFunction} by multiple threads. * * @param the type of the elements in the array * @param a the array to be sorted * @param keyExtractor the function used to extract the double key for comparison */ public static void parallelSortByDouble(final T[] a, final ToDoubleFunction keyExtractor) { parallelSort(a, Comparators.comparingDouble(keyExtractor)); } /** * Sorts the specified list based on the double values extracted by the provided {@code ToDoubleFunction} by multiple threads. * * @param the type of the elements in the list * @param list the list to be sorted * @param keyExtractor the function used to extract the double key for comparison */ public static void parallelSortByDouble(final List list, final ToDoubleFunction keyExtractor) { parallelSort(list, Comparators.comparingDouble(keyExtractor)); } /** * Sorts the specified array of booleans in reverse order. * * @param a the array to be sorted */ public static void reverseSort(final boolean[] a) { if (isEmpty(a)) { return; } reverseSort(a, 0, a.length); } /** * Sorts the specified range of the array of booleans in reverse order. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws IndexOutOfBoundsException if the specified range is out of bounds */ public static void reverseSort(final boolean[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (a == null || toIndex - fromIndex <= 1) { return; } int numOfTrue = 0; for (int i = fromIndex; i < toIndex; i++) { if (a[i]) { numOfTrue++; } } fill(a, fromIndex, numOfTrue, true); fill(a, fromIndex + numOfTrue, toIndex, false); } /** * Sorts the specified array of characters in reverse order. * * @param a the array to be sorted */ public static void reverseSort(final char[] a) { sort(a); reverse(a); } /** * Sorts the specified range of the array of characters in reverse order. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws ArrayIndexOutOfBoundsException if fromIndex or toIndex is out of range */ public static void reverseSort(final char[] a, final int fromIndex, final int toIndex) throws ArrayIndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (toIndex - fromIndex <= 1) { return; } sort(a, fromIndex, toIndex); reverse(a, fromIndex, toIndex); } /** * Sorts the specified array of bytes in reverse order. * * @param a the array to be sorted */ public static void reverseSort(final byte[] a) { sort(a); reverse(a); } /** * Sorts the specified range of the array of bytes in reverse order. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws ArrayIndexOutOfBoundsException if fromIndex or toIndex is out of range */ public static void reverseSort(final byte[] a, final int fromIndex, final int toIndex) throws ArrayIndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (toIndex - fromIndex <= 1) { return; } sort(a, fromIndex, toIndex); reverse(a, fromIndex, toIndex); } /** * Sorts the specified array of shorts in reverse order. * * @param a the array to be sorted */ public static void reverseSort(final short[] a) { sort(a); reverse(a); } /** * Sorts the specified range of the array of shorts in reverse order. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws ArrayIndexOutOfBoundsException if fromIndex or toIndex is out of range */ public static void reverseSort(final short[] a, final int fromIndex, final int toIndex) throws ArrayIndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (toIndex - fromIndex <= 1) { return; } sort(a, fromIndex, toIndex); reverse(a, fromIndex, toIndex); } /** * Sorts the specified array of ints in reverse order. * * @param a the array to be sorted */ public static void reverseSort(final int[] a) { sort(a); reverse(a); } /** * Sorts the specified range of the array of ints in reverse order. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws ArrayIndexOutOfBoundsException if fromIndex or toIndex is out of range */ public static void reverseSort(final int[] a, final int fromIndex, final int toIndex) throws ArrayIndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (toIndex - fromIndex <= 1) { return; } sort(a, fromIndex, toIndex); reverse(a, fromIndex, toIndex); } /** * Sorts the specified array of longs in reverse order. * * @param a the array to be sorted */ public static void reverseSort(final long[] a) { sort(a); reverse(a); } /** * Sorts the specified range of the array of longs in reverse order. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws ArrayIndexOutOfBoundsException if fromIndex or toIndex is out of range */ public static void reverseSort(final long[] a, final int fromIndex, final int toIndex) throws ArrayIndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (toIndex - fromIndex <= 1) { return; } sort(a, fromIndex, toIndex); reverse(a, fromIndex, toIndex); } /** * Sorts the specified array of floats in reverse order. * * @param a the array to be sorted */ public static void reverseSort(final float[] a) { sort(a); reverse(a); } /** * Sorts the specified range of the array of floats in reverse order. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws ArrayIndexOutOfBoundsException if fromIndex or toIndex is out of range */ public static void reverseSort(final float[] a, final int fromIndex, final int toIndex) throws ArrayIndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (toIndex - fromIndex <= 1) { return; } sort(a, fromIndex, toIndex); reverse(a, fromIndex, toIndex); } /** * Sorts the specified array of doubles in reverse order. * * @param a the array to be sorted */ public static void reverseSort(final double[] a) { sort(a); reverse(a); } /** * Sorts the specified range of the array of doubles in reverse order. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws ArrayIndexOutOfBoundsException if fromIndex or toIndex is out of range */ public static void reverseSort(final double[] a, final int fromIndex, final int toIndex) throws ArrayIndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (toIndex - fromIndex <= 1) { return; } sort(a, fromIndex, toIndex); reverse(a, fromIndex, toIndex); } /** * Sorts the specified array of objects in reverse order. (where {@code null} is maximum) * * @param a the array to be sorted */ public static void reverseSort(final Object[] a) { sort(a, REVERSED_COMPARATOR); } /** * Sorts the specified range of the array of objects in reverse order. (where {@code null} is maximum) * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws ArrayIndexOutOfBoundsException if fromIndex or toIndex is out of range */ public static void reverseSort(final Object[] a, final int fromIndex, final int toIndex) throws ArrayIndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (toIndex - fromIndex <= 1) { return; } sort(a, fromIndex, toIndex, REVERSED_COMPARATOR); } /** * Sorts the specified list in reverse order. (where {@code null} is maximum) * * @param * @param list the list to be sorted */ public static > void reverseSort(final List list) { sort(list, REVERSED_COMPARATOR); } /** * Sorts the specified range of the list in reverse order. (where {@code null} is maximum) * * @param * @param list the list to be sorted * @param fromIndex the index of the first element (inclusive) to be sorted * @param toIndex the index of the last element (exclusive) to be sorted * @throws ArrayIndexOutOfBoundsException if fromIndex or toIndex is out of range */ public static > void reverseSort(final List list, final int fromIndex, final int toIndex) throws ArrayIndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, list == null ? 0 : list.size()); if (toIndex - fromIndex <= 1) { return; } sort(list, fromIndex, toIndex, REVERSED_COMPARATOR); } /** * Sorts the specified array based on the keys extracted by the provided {@code Function} in reverse order. * * @param the type of elements in the array * @param the type of keys extracted from the elements, which must be comparable * @param a the array to be sorted * @param keyExtractor the function to extract the keys from the elements */ public static > void reverseSortBy(final T[] a, final Function keyExtractor) { sort(a, Comparators.reversedComparingBy(keyExtractor)); } /** * Sorts the specified list based on the keys extracted by the provided {@code Function} in reverse order. * * @param the type of elements in the list * @param the type of keys extracted from the elements, which must be comparable * @param list the list to be sorted * @param keyExtractor the function to extract the keys from the elements */ public static > void reverseSortBy(final List list, final Function keyExtractor) { sort(list, Comparators.reversedComparingBy(keyExtractor)); } /** * Sorts the specified array based on the int values extracted by the provided {@code ToIntFunction} in reverse order. * * @param the type of elements in the array * @param a the array to be sorted * @param keyExtractor the function to extract the int key from the elements */ public static void reverseSortByInt(final T[] a, final ToIntFunction keyExtractor) { sort(a, Comparators.reversedComparingInt(keyExtractor)); } /** * Sorts the specified list based on the int values extracted by the provided {@code ToIntFunction} in reverse order. * * @param the type of elements in the list * @param list the list to be sorted * @param keyExtractor the function to extract the int key from the elements */ public static void reverseSortByInt(final List list, final ToIntFunction keyExtractor) { sort(list, Comparators.reversedComparingInt(keyExtractor)); } /** * Sorts the specified array based on the long values extracted by the provided {@code ToLongFunction} in reverse order. * * @param the type of elements in the array * @param a the array to be sorted * @param keyExtractor the function to extract the long key from the elements */ public static void reverseSortByLong(final T[] a, final ToLongFunction keyExtractor) { sort(a, Comparators.reversedComparingLong(keyExtractor)); } /** * Sorts the specified list based on the long values extracted by the provided {@code ToLongFunction} in reverse order. * * @param the type of elements in the list * @param list the list to be sorted * @param keyExtractor the function to extract the long key from the elements */ public static void reverseSortByLong(final List list, final ToLongFunction keyExtractor) { sort(list, Comparators.reversedComparingLong(keyExtractor)); } /** * Sorts the specified array based on the float values extracted by the provided {@code ToFloatFunction} in reverse order. * * @param the type of elements in the array * @param a the array to be sorted * @param keyExtractor the function to extract the float key from the elements */ public static void reverseSortByFloat(final T[] a, final ToFloatFunction keyExtractor) { sort(a, Comparators.reversedComparingFloat(keyExtractor)); } /** * Sorts the specified list based on the float values extracted by the provided {@code ToFloatFunction} in reverse order. * * @param the type of elements in the list * @param list the list to be sorted * @param keyExtractor the function to extract the float key from the elements */ public static void reverseSortByFloat(final List list, final ToFloatFunction keyExtractor) { sort(list, Comparators.reversedComparingFloat(keyExtractor)); } /** * Sorts the specified array based on the double values extracted by the provided {@code ToDoubleFunction} in reverse order. * * @param the type of elements in the array * @param a the array to be sorted * @param keyExtractor the function to extract the double key from the elements */ public static void reverseSortByDouble(final T[] a, final ToDoubleFunction keyExtractor) { sort(a, Comparators.reversedComparingDouble(keyExtractor)); } /** * Sorts the specified list based on the double values extracted by the provided {@code ToDoubleFunction} in reverse order. * * @param the type of elements in the list * @param list the list to be sorted * @param keyExtractor the function to extract the double key from the elements */ public static void reverseSortByDouble(final List list, final ToDoubleFunction keyExtractor) throws IndexOutOfBoundsException { sort(list, Comparators.reversedComparingDouble(keyExtractor)); } // /** // * // * @param a // */ // public static void bucketSort(final int[] a) { // if (isEmpty(a)) { // return; // } // // bucketSort(a, 0, a.length); // } // // /** // * // * @param a // * @param fromIndex // * @param toIndex // */ // public static void bucketSort(final int[] a, final int fromIndex, final int toIndex) { // checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); // // if (isEmpty(a) || fromIndex == toIndex) { // return; // } // // if (toIndex - fromIndex < 32) { // sort(a, fromIndex, toIndex); // return; // } // // final Multiset multiset = new Multiset<>(); // // for (int i = fromIndex; i < toIndex; i++) { // multiset.add(a[i]); // } // // final Map m = multiset.toMapSortedBy((a1, b) -> compare(a1.getKey().intValue(), a1.getKey().intValue())); // int idx = fromIndex; // // for (Map.Entry entry : m.entrySet()) { // fill(a, idx, idx + entry.getValue(), entry.getKey()); // idx += entry.getValue(); // } // } // // /** // * // * @param a // */ // public static void bucketSort(final long[] a) { // if (isEmpty(a)) { // return; // } // // bucketSort(a, 0, a.length); // } // // /** // * // * @param a // * @param fromIndex // * @param toIndex // */ // public static void bucketSort(final long[] a, final int fromIndex, final int toIndex) { // checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); // // if (isEmpty(a) || fromIndex == toIndex) { // return; // } // // if (toIndex - fromIndex < 32) { // sort(a, fromIndex, toIndex); // return; // } // // final Multiset multiset = new Multiset<>(); // // for (int i = fromIndex; i < toIndex; i++) { // multiset.add(a[i]); // } // // final Map m = multiset.toMapSortedBy((a1, b) -> compare(a1.getKey().longValue(), a1.getKey().longValue())); // // int idx = fromIndex; // // for (Map.Entry entry : m.entrySet()) { // fill(a, idx, idx + entry.getValue(), entry.getKey()); // idx += entry.getValue(); // } // } // // /** // * // * @param a // */ // public static void bucketSort(final float[] a) { // if (isEmpty(a)) { // return; // } // // bucketSort(a, 0, a.length); // } // // /** // * // * @param a // * @param fromIndex // * @param toIndex // */ // public static void bucketSort(final float[] a, final int fromIndex, final int toIndex) { // checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); // // if (isEmpty(a) || fromIndex == toIndex) { // return; // } // // if (toIndex - fromIndex < 32) { // sort(a, fromIndex, toIndex); // return; // } // // final Multiset multiset = new Multiset<>(); // // for (int i = fromIndex; i < toIndex; i++) { // multiset.add(a[i]); // } // // final Map m = multiset.toMapSortedBy((a1, b) -> compare(a1.getKey(), a1.getKey())); // int idx = fromIndex; // // for (Map.Entry entry : m.entrySet()) { // fill(a, idx, idx + entry.getValue(), entry.getKey()); // idx += entry.getValue(); // } // } // // /** // * // * @param a // */ // public static void bucketSort(final double[] a) { // if (isEmpty(a)) { // return; // } // // bucketSort(a, 0, a.length); // } // // /** // * // * @param a // * @param fromIndex // * @param toIndex // */ // public static void bucketSort(final double[] a, final int fromIndex, final int toIndex) { // checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); // // if (isEmpty(a) || fromIndex == toIndex) { // return; // } // // if (toIndex - fromIndex < 32) { // sort(a, fromIndex, toIndex); // return; // } // // final Multiset multiset = new Multiset<>(); // // for (int i = fromIndex; i < toIndex; i++) { // multiset.add(a[i]); // } // // final Map m = multiset.toMapSortedBy((a1, b) -> compare(a1.getKey(), a1.getKey())); // int idx = fromIndex; // // for (Map.Entry entry : m.entrySet()) { // fill(a, idx, idx + entry.getValue(), entry.getKey()); // idx += entry.getValue(); // } // } // // /** // * Note: All the objects with same value will be replaced by first element with the same value. // * // * @param a // */ // public static void bucketSort(final Object[] a) { // if (isEmpty(a)) { // return; // } // // bucketSort(a, 0, a.length); // } // // /** // * Note: All the objects with same value will be replaced by first element with the same value. // * // * @param a the elements in the array must implements the Comparable interface. // * @param fromIndex // * @param toIndex // */ // public static void bucketSort(final Object[] a, final int fromIndex, final int toIndex) { // bucketSort(a, fromIndex, toIndex, NATURAL_COMPARATOR); // } // // /** // * // * @param // * @param a // * @param cmp // */ // public static void bucketSort(final T[] a, final Comparator cmp) { // if (isEmpty(a)) { // return; // } // // bucketSort(a, 0, a.length, cmp); // } // // /** // * Note: All the objects with same value will be replaced by first element with the same value. // * // * @param // * @param a // * @param fromIndex // * @param toIndex // * @param cmp // */ // public static void bucketSort(final T[] a, final int fromIndex, final int toIndex, final Comparator cmp) { // checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); // // if (isEmpty(a) || fromIndex == toIndex) { // return; // } // // if (toIndex - fromIndex < 32) { // sort(a, fromIndex, toIndex, cmp); // return; // } // // final Comparator comparator = checkComparator(cmp); // final Multiset multiset = new Multiset<>(); // // for (int i = fromIndex; i < toIndex; i++) { // multiset.add(a[i]); // } // // final Map m = multiset.toMapSortedBy((a1, b) -> comparator.compare(a1.getKey(), a1.getKey())); // int idx = fromIndex; // // for (Map.Entry entry : m.entrySet()) { // fill(a, idx, idx + entry.getValue(), entry.getKey()); // idx += entry.getValue(); // } // } // // /** // * Note: All the objects with same value will be replaced by first element with the same value. // * // * @param // * @param list // */ // public static > void bucketSort(final List list) { // if (isEmpty(list)) { // return; // } // // bucketSort(list, 0, list.size()); // } // // /** // * Note: All the objects with same value will be replaced by first element with the same value. // * // * @param // * @param list // * @param fromIndex // * @param toIndex // */ // public static > void bucketSort(final List list, final int fromIndex, final int toIndex) { // bucketSort(list, fromIndex, toIndex, NATURAL_COMPARATOR); // } // // /** // * Note: All the objects with same value will be replaced by first element with the same value. // * // * @param // * @param list // * @param cmp // */ // public static void bucketSort(final List list, final Comparator cmp) { // if (isEmpty(list)) { // return; // } // // bucketSort(list, 0, list.size(), cmp); // } // // /** // * Note: All the objects with same value will be replaced by first element with the same value. // * // * @param // * @param list // * @param fromIndex // * @param toIndex // * @param cmp // */ // public static void bucketSort(final List list, final int fromIndex, final int toIndex, final Comparator cmp) { // checkFromToIndex(fromIndex, toIndex, list == null ? 0 : list.size()); // // if ((isEmpty(list) && fromIndex == 0 && toIndex == 0) || fromIndex == toIndex) { // return; // } // // if (toIndex - fromIndex < 32) { // sort(list, fromIndex, toIndex, cmp); // return; // } // // final Comparator comparator = checkComparator(cmp); // final Multiset multiset = new Multiset<>(); // ListIterator itr = (ListIterator) list.listIterator(fromIndex); // int i = fromIndex; // // while (itr.hasNext()) { // if (i++ >= toIndex) { // break; // } // // multiset.add(itr.next()); // } // // final Map m = multiset.toMapSortedBy((a, b) -> comparator.compare(a.getKey(), a.getKey())); // // itr = (ListIterator) list.listIterator(fromIndex); // // for (Map.Entry entry : m.entrySet()) { // final T key = entry.getKey(); // for (int j = 0; j < entry.getValue(); j++) { // itr.next(); // itr.set(key); // } // } // } // // /** // * Bucket sort by. // * // * @param // * @param // * @param a // * @param keyExtractor // */ // public static > void bucketSortBy(final T[] a, final Function keyExtractor) { // if (isEmpty(a)) { // return; // } // // bucketSort(a, Comparators.comparingBy(keyExtractor)); // } // // /** // * Bucket sort by. // * // * @param // * @param // * @param list // * @param keyExtractor // */ // public static > void bucketSortBy(final List list, final Function keyExtractor) { // if (isEmpty(list)) { // return; // } // // bucketSort(list, Comparators.comparingBy(keyExtractor)); // } /** * Performs a binary search on the specified array of booleans to find the specified value. * The array must be sorted (as by the {@link #sort(boolean[])} method) before making this call. * If it is not sorted, the results are undefined. * If the array contains multiple elements with the specified value, there is no guarantee which one will be found. * * @param a the array to be searched. It must be sorted in ascending order * @param valueToFind the value to be searched for * @return the index of the value to be searched, if it is contained in the array within the specified range; * otherwise, (-(insertion point) - 1), or -1 if the array is {@code null} or empty. */ static int binarySearch(final boolean[] a, final boolean valueToFind) { if (isEmpty(a)) { return INDEX_NOT_FOUND; } if (a[0] == valueToFind) { return 0; } else if (a[a.length - 1] != valueToFind) { return !valueToFind ? -1 : -(a.length + 1); } int left = 0, right = a.length - 1; while (left < right) { final int mid = left + (right - left) / 2; if (a[mid] == valueToFind) { right = mid; } else { left = mid + 1; } } return left; } /** * Performs a binary search on the specified array of characters to find the specified value. * The array must be sorted (as by the {@link #sort(char[])} method) before making this call. * If it is not sorted, the results are undefined. * If the array contains multiple elements with the specified value, there is no guarantee which one will be found. * * @param a the array to be searched. It must be sorted in ascending order * @param valueToFind the value to be searched for * @return the index of the value to be searched, if it is contained in the array within the specified range; * otherwise, (-(insertion point) - 1), or -1 if the array is {@code null} or empty. * @see Arrays#binarySearch(char[], char) */ public static int binarySearch(final char[] a, final char valueToFind) { if (isEmpty(a)) { return INDEX_NOT_FOUND; } return Arrays.binarySearch(a, valueToFind); } /** * Performs a binary search on the specified range of the array of characters to find the specified value. * The range must be sorted (as by the {@link #sort(char[], int, int)} method) before making this call. * If it is not sorted, the results are undefined. * If the range contains multiple elements with the specified value, there is no guarantee which one will be found. * * @param a the array to be searched. It must be sorted in ascending order. * @param fromIndex the index of the first element (inclusive) to be searched. * @param toIndex the index of the last element (exclusive) to be searched. * @param valueToFind the value to be searched for. * @return the index of the value to be searched, if it is contained in the array within the specified range; * otherwise, (-(insertion point) - 1), or -1 if the array is {@code null} or empty. * @throws IndexOutOfBoundsException if the range is out of bounds. * @see Arrays#binarySearch(char[], int, int, char) */ public static int binarySearch(final char[] a, final int fromIndex, final int toIndex, final char valueToFind) { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a)) { return INDEX_NOT_FOUND; } return Arrays.binarySearch(a, fromIndex, toIndex, valueToFind); } /** * Performs a binary search on the specified array of bytes to find the specified value. * The array must be sorted (as by the {@link #sort(byte[])} method) before making this call. * If it is not sorted, the results are undefined. * If the array contains multiple elements with the specified value, there is no guarantee which one will be found. * * @param a the array to be searched. It must be sorted in ascending order * @param valueToFind the value to be searched for * @return the index of the value to be searched, if it is contained in the array within the specified range; * otherwise, (-(insertion point) - 1), or -1 if the array is {@code null} or empty. * @see Arrays#binarySearch(byte[], byte) */ public static int binarySearch(final byte[] a, final byte valueToFind) { if (isEmpty(a)) { return INDEX_NOT_FOUND; } return Arrays.binarySearch(a, valueToFind); } /** * Performs a binary search on the specified range of the array of bytes to find the specified value. * The range must be sorted (as by the {@link #sort(byte[], int, int)} method)before making this call. * If it is not sorted, the results are undefined. * If the range contains multiple elements with the specified value, there is no guarantee which one will be found. * * @param a the array to be searched. It must be sorted in ascending order. * @param fromIndex the index of the first element (inclusive) to be searched. * @param toIndex the index of the last element (exclusive) to be searched. * @param valueToFind the value to be searched for. * @return the index of the value to be searched, if it is contained in the array within the specified range; * otherwise, (-(insertion point) - 1), or -1 if the array is {@code null} or empty. * @throws IndexOutOfBoundsException if the range is out of bounds. * @see Arrays#binarySearch(byte[], int, int, byte) */ public static int binarySearch(final byte[] a, final int fromIndex, final int toIndex, final byte valueToFind) { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a)) { return INDEX_NOT_FOUND; } return Arrays.binarySearch(a, fromIndex, toIndex, valueToFind); } /** * Performs a binary search on the specified array of shorts to find the specified value. * The array must be sorted (as by the {@link #sort(short[])} method)before making this call. * If it is not sorted, the results are undefined. * If the array contains multiple elements with the specified value, there is no guarantee which one will be found. * * @param a the array to be searched. It must be sorted in ascending order * @param valueToFind the value to be searched for * @return the index of the value to be searched, if it is contained in the array within the specified range; * otherwise, (-(insertion point) - 1), or -1 if the array is {@code null} or empty. * @see Arrays#binarySearch(short[], short) */ public static int binarySearch(final short[] a, final short valueToFind) { if (isEmpty(a)) { return INDEX_NOT_FOUND; } return Arrays.binarySearch(a, valueToFind); } /** * Performs a binary search on the specified range of the array of shorts to find the specified value. * The range must be sorted (as by the {@link #sort(short[], int, int)} method)before making this call. * If it is not sorted, the results are undefined. * If the range contains multiple elements with the specified value, there is no guarantee which one will be found. * * @param a the array to be searched. It must be sorted in ascending order. * @param fromIndex the index of the first element (inclusive) to be searched. * @param toIndex the index of the last element (exclusive) to be searched. * @param valueToFind the value to be searched for. * @return the index of the value to be searched, if it is contained in the array within the specified range; * otherwise, (-(insertion point) - 1), or -1 if the array is {@code null} or empty. * @throws IndexOutOfBoundsException if the range is out of bounds. * @see Arrays#binarySearch(short[], int, int, short) */ public static int binarySearch(final short[] a, final int fromIndex, final int toIndex, final short valueToFind) { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a)) { return INDEX_NOT_FOUND; } return Arrays.binarySearch(a, fromIndex, toIndex, valueToFind); } /** * Performs a binary search on the specified array of ints to find the specified value. * The array must be sorted (as by the {@link #sort(int[])} method)before making this call. * If it is not sorted, the results are undefined. * If the array contains multiple elements with the specified value, there is no guarantee which one will be found. * * @param a the array to be searched. It must be sorted in ascending order * @param valueToFind the value to be searched for * @return the index of the value to be searched, if it is contained in the array within the specified range; * otherwise, (-(insertion point) - 1), or -1 if the array is {@code null} or empty. * @see Arrays#binarySearch(int[], int) */ public static int binarySearch(final int[] a, final int valueToFind) { if (isEmpty(a)) { return INDEX_NOT_FOUND; } return Arrays.binarySearch(a, valueToFind); } /** * Performs a binary search on the specified range of the array of ints to find the specified value. * The range must be sorted (as by the {@link #sort(int[], int, int)} method) before making this call. * If it is not sorted, the results are undefined. * If the range contains multiple elements with the specified value, there is no guarantee which one will be found. * * @param a the array to be searched. It must be sorted in ascending order. * @param fromIndex the index of the first element (inclusive) to be searched. * @param toIndex the index of the last element (exclusive) to be searched. * @param valueToFind the value to be searched for. * @return the index of the value to be searched, if it is contained in the array within the specified range; * otherwise, (-(insertion point) - 1), or -1 if the array is {@code null} or empty. * @throws IndexOutOfBoundsException if the range is out of bounds. * @see Arrays#binarySearch(int[], int, int, int) */ public static int binarySearch(final int[] a, final int fromIndex, final int toIndex, final int valueToFind) { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a)) { return INDEX_NOT_FOUND; } return Arrays.binarySearch(a, fromIndex, toIndex, valueToFind); } /** * Performs a binary search on the specified array of longs to find the specified value. * The array must be sorted (as by the {@link #sort(long[])} method)before making this call. * If it is not sorted, the results are undefined. * If the array contains multiple elements with the specified value, there is no guarantee which one will be found. * * @param a the array to be searched. It must be sorted in ascending order * @param valueToFind the value to be searched for * @return the index of the value to be searched, if it is contained in the array within the specified range; * otherwise, (-(insertion point) - 1), or -1 if the array is {@code null} or empty. * @see Arrays#binarySearch(long[], long) */ public static int binarySearch(final long[] a, final long valueToFind) { if (isEmpty(a)) { return INDEX_NOT_FOUND; } return Arrays.binarySearch(a, valueToFind); } /** * Performs a binary search on the specified range of the array of longs to find the specified value. * The range must be sorted (as by the {@link #sort(long[], int, int)} method)before making this call. * If it is not sorted, the results are undefined. * If the range contains multiple elements with the specified value, there is no guarantee which one will be found. * * @param a the array to be searched. It must be sorted in ascending order. * @param fromIndex the index of the first element (inclusive) to be searched. * @param toIndex the index of the last element (exclusive) to be searched. * @param valueToFind the value to be searched for. * @return the index of the value to be searched, if it is contained in the array within the specified range; * otherwise, (-(insertion point) - 1), or -1 if the array is {@code null} or empty. * @throws IndexOutOfBoundsException if the range is out of bounds. * @see Arrays#binarySearch(long[], int, int, long) */ public static int binarySearch(final long[] a, final int fromIndex, final int toIndex, final long valueToFind) { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a)) { return INDEX_NOT_FOUND; } return Arrays.binarySearch(a, fromIndex, toIndex, valueToFind); } /** * Performs a binary search on the specified array of floats to find the specified value. * The array must be sorted (as by the {@link #sort(float[])} method)before making this call. * If it is not sorted, the results are undefined. * If the array contains multiple elements with the specified value, there is no guarantee which one will be found. * * @param a the array to be searched. It must be sorted in ascending order * @param valueToFind the value to be searched for * @return the index of the value to be searched, if it is contained in the array within the specified range; * otherwise, (-(insertion point) - 1), or -1 if the array is {@code null} or empty. * @see Arrays#binarySearch(float[], float) */ public static int binarySearch(final float[] a, final float valueToFind) { if (isEmpty(a)) { return INDEX_NOT_FOUND; } return Arrays.binarySearch(a, valueToFind); } /** * Performs a binary search on the specified range of the array of floats to find the specified value. * The range must be sorted (as by the {@link #sort(float[], int, int)} method)before making this call. * If it is not sorted, the results are undefined. * If the range contains multiple elements with the specified value, there is no guarantee which one will be found. * * @param a the array to be searched. It must be sorted in ascending order. * @param fromIndex the index of the first element (inclusive) to be searched. * @param toIndex the index of the last element (exclusive) to be searched. * @param valueToFind the value to be searched for. * @return the index of the value to be searched, if it is contained in the array within the specified range; * otherwise, (-(insertion point) - 1), or -1 if the array is {@code null} or empty. * @throws IndexOutOfBoundsException if the range is out of bounds. * @see Arrays#binarySearch(float[], int, int, float) */ public static int binarySearch(final float[] a, final int fromIndex, final int toIndex, final float valueToFind) { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a)) { return INDEX_NOT_FOUND; } return Arrays.binarySearch(a, fromIndex, toIndex, valueToFind); } /** * Performs a binary search on the specified array of doubles to find the specified value. * The array must be sorted (as by the {@link #sort(double[])} method)before making this call. * If it is not sorted, the results are undefined. * If the array contains multiple elements with the specified value, there is no guarantee which one will be found. * * @param a the array to be searched. It must be sorted in ascending order * @param valueToFind the value to be searched for * @return the index of the value to be searched, if it is contained in the array within the specified range; * otherwise, (-(insertion point) - 1), or -1 if the array is {@code null} or empty. * @see Arrays#binarySearch(double[], double) */ public static int binarySearch(final double[] a, final double valueToFind) { if (isEmpty(a)) { return INDEX_NOT_FOUND; } return Arrays.binarySearch(a, valueToFind); } /** * Performs a binary search on the specified range of the array of doubles to find the specified value. * The range must be sorted (as by the {@link #sort(double[], int, int)} method)before making this call. * If it is not sorted, the results are undefined. * If the range contains multiple elements with the specified value, there is no guarantee which one will be found. * * @param a the array to be searched. It must be sorted in ascending order. * @param fromIndex the index of the first element (inclusive) to be searched. * @param toIndex the index of the last element (exclusive) to be searched. * @param valueToFind the value to be searched for. * @return the index of the value to be searched, if it is contained in the array within the specified range; * otherwise, (-(insertion point) - 1), or -1 if the array is {@code null} or empty. * @throws IndexOutOfBoundsException if the range is out of bounds. * @see Arrays#binarySearch(double[], int, int, double) */ public static int binarySearch(final double[] a, final int fromIndex, final int toIndex, final double valueToFind) { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a)) { return INDEX_NOT_FOUND; } return Arrays.binarySearch(a, fromIndex, toIndex, valueToFind); } /** * Performs a binary search on the specified array of objects to find the specified value. * The array must be sorted (as by the {@link #sort(Object[])} method)before making this call. * If it is not sorted, the results are undefined. * If the array contains multiple elements with the specified value, there is no guarantee which one will be found. * * @param a the array to be searched. It must be sorted in ascending order * @param valueToFind the value to be searched for * @return the index of the value to be searched, if it is contained in the array within the specified range; * otherwise, (-(insertion point) - 1), or -1 if the array is {@code null} or empty. * @see Arrays#binarySearch(Object[], Object) */ public static int binarySearch(final Object[] a, final Object valueToFind) { if (isEmpty(a)) { return INDEX_NOT_FOUND; } return Arrays.binarySearch(a, valueToFind); } /** * Performs a binary search on the specified range of the array of objects to find the specified value. * The range must be sorted (as by the {@link #sort(Object[], int, int)} method)before making this call. * If it is not sorted, the results are undefined. * If the range contains multiple elements with the specified value, there is no guarantee which one will be found. * * @param a the array to be searched. It must be sorted in ascending order. * @param fromIndex the index of the first element (inclusive) to be searched. * @param toIndex the index of the last element (exclusive) to be searched. * @param valueToFind the value to be searched for. * @return the index of the value to be searched, if it is contained in the array within the specified range; * otherwise, (-(insertion point) - 1), or -1 if the array is {@code null} or empty. * @throws IndexOutOfBoundsException if the range is out of bounds. * @see Arrays#binarySearch(Object[], int, int, Object) */ public static int binarySearch(final Object[] a, final int fromIndex, final int toIndex, final Object valueToFind) { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a)) { return INDEX_NOT_FOUND; } return Arrays.binarySearch(a, fromIndex, toIndex, valueToFind); } /** * Performs a binary search on the specified array of objects to find the specified value. * The array must be sorted (as by the {@link #sort(Object[], Comparator)} method)before making this call. * If it is not sorted, the results are undefined. * If the array contains multiple elements with the specified value, there is no guarantee which one will be found. * * @param the type of the elements in the array * @param a the array to be searched. It must be sorted in ascending order * @param valueToFind the value to be searched for * @param cmp the comparator by which the array is ordered * @return the index of the value to be searched, if it is contained in the array within the specified range; * otherwise, (-(insertion point) - 1), or -1 if the array is {@code null} or empty. * @see Arrays#binarySearch(Object[], Object, Comparator) */ public static int binarySearch(final T[] a, final T valueToFind, final Comparator cmp) { if (isEmpty(a)) { return INDEX_NOT_FOUND; } return Arrays.binarySearch(a, valueToFind, checkComparator(cmp)); } /** * Performs a binary search on the specified range of the array of objects to find the specified value. * The range must be sorted (as by the {@link #sort(Object[], int, int, Comparator)} method)before making this call. * If it is not sorted, the results are undefined. * If the range contains multiple elements with the specified value, there is no guarantee which one will be found. * * @param the type of the elements in the array * @param a the array to be searched. It must be sorted in ascending order. * @param fromIndex the index of the first element (inclusive) to be searched. * @param toIndex the index of the last element (exclusive) to be searched. * @param valueToFind the value to be searched for. * @param cmp the comparator by which the array is ordered * @return the index of the value to be searched, if it is contained in the array within the specified range; * otherwise, (-(insertion point) - 1), or -1 if the array is {@code null} or empty. * @throws IndexOutOfBoundsException if the range is out of bounds. * @see Arrays#binarySearch(Object[], int, int, Object, Comparator) */ public static int binarySearch(final T[] a, final int fromIndex, final int toIndex, final T valueToFind, final Comparator cmp) { checkFromToIndex(fromIndex, toIndex, a == null ? 0 : a.length); if (isEmpty(a)) { return INDEX_NOT_FOUND; } return Arrays.binarySearch(a, fromIndex, toIndex, valueToFind, checkComparator(cmp)); } /** * Performs a binary search on the specified list of objects to find the specified value. * The list must be sorted (as by the {@link #sort(List)} method)before making this call. * If it is not sorted, the results are undefined. * If the list contains multiple elements with the specified value, there is no guarantee which one will be found. * * @param the type of the elements in the list * @param list the list to be searched. It must be sorted in ascending order * @param valueToFind the value to be searched for * @return the index of the value to be searched, if it is contained in the list within the specified range; * otherwise, (-(insertion point) - 1), or -1 if the list is {@code null} or empty. * @see Collections#binarySearch(List, Object) */ public static > int binarySearch(final List list, final T valueToFind) { if (isEmpty(list)) { return INDEX_NOT_FOUND; } return Collections.binarySearch(list, valueToFind); } /** * Performs a binary search on the specified range of the list of objects to find the specified value. * The range must be sorted (as by the {@link #sort(List, int, int)} method)before making this call. * If it is not sorted, the results are undefined. * If the range contains multiple elements with the specified value, there is no guarantee which one will be found. * * @param the type of the elements in the list * @param list the list to be searched. It must be sorted in ascending order. * @param fromIndex the index of the first element (inclusive) to be searched. * @param toIndex the index of the last element (exclusive) to be searched. * @param valueToFind the value to be searched for. * @return the index of the value to be searched, if it is contained in the list within the specified range; * otherwise, (-(insertion point) - 1), or -1 if the list is {@code null} or empty. * @throws IndexOutOfBoundsException if the range is out of bounds. * @see Collections#binarySearch(List, Object) */ public static > int binarySearch(final List list, final int fromIndex, final int toIndex, final T valueToFind) { checkFromToIndex(fromIndex, toIndex, size(list)); if (isEmpty(list)) { return INDEX_NOT_FOUND; } return binarySearch(list, fromIndex, toIndex, valueToFind, NATURAL_COMPARATOR); } /** * Performs a binary search on the specified list of objects to find the specified value. * The list must be sorted (as by the {@link #sort(List, Comparator)} method)before making this call. * If it is not sorted, the results are undefined. * If the list contains multiple elements with the specified value, there is no guarantee which one will be found. * * @param the type of the elements in the list * @param list the list to be searched. It must be sorted in ascending order * @param valueToFind the value to be searched for * @param cmp the comparator by which the list is ordered * @return the index of the value to be searched, if it is contained in the list within the specified range; * otherwise, (-(insertion point) - 1), or -1 if the list is {@code null} or empty. * @see Collections#binarySearch(List, Object, Comparator) */ public static int binarySearch(final List list, final T valueToFind, final Comparator cmp) { if (isEmpty(list)) { return INDEX_NOT_FOUND; } return Collections.binarySearch(list, valueToFind, checkComparator(cmp)); } /** * Performs a binary search on the specified range of the list of objects to find the specified value. * The range must be sorted (as by the {@link #sort(List, int, int, Comparator)} method)before making this call. * If it is not sorted, the results are undefined. * If the range contains multiple elements with the specified value, there is no guarantee which one will be found. * * @param the type of the elements in the list * @param list the list to be searched. It must be sorted in ascending order. * @param fromIndex the index of the first element (inclusive) to be searched. * @param toIndex the index of the last element (exclusive) to be searched. * @param valueToFind the value to be searched for. * @param cmp the comparator by which the list is ordered * @return the index of the value to be searched, if it is contained in the list within the specified range; * otherwise, (-(insertion point) - 1), or -1 if the list is {@code null} or empty. * @throws IndexOutOfBoundsException if the range is out of bounds. * @see Collections#binarySearch(List, Object, Comparator) */ public static int binarySearch(final List list, final int fromIndex, final int toIndex, final T valueToFind, Comparator cmp) { if (isEmpty(list)) { return INDEX_NOT_FOUND; } cmp = checkComparator(cmp); if (fromIndex == 0 && toIndex == list.size()) { return Collections.binarySearch(list, valueToFind, cmp); } @SuppressWarnings("deprecation") final T[] a = (T[]) InternalUtil.getInternalArray(list); if (a != null) { return binarySearch(a, fromIndex, toIndex, valueToFind, cmp); } final int ret = Collections.binarySearch(list.subList(fromIndex, toIndex), valueToFind, cmp); return ret >= 0 ? ret + fromIndex : ret - fromIndex; } /** * Returns the index of the first occurrence of the specified value in the array. * * @param a the array to be searched * @param valueToFind the value to be searched for * @return the index of the first occurrence of the specified value in the array, * or -1 if the array is {@code null} or empty or does not contain the value */ public static int indexOf(final boolean[] a, final boolean valueToFind) { return indexOf(a, valueToFind, 0); } /** * Returns the index of the first occurrence of the specified value in the array, starting the search at the specified index. * * @param a the array to be searched * @param valueToFind the value to be searched for * @param fromIndex the index to start the search from * @return the index of the first occurrence of the specified value in the array, * or -1 if the array is {@code null} or empty or does not contain the value */ public static int indexOf(final boolean[] a, final boolean valueToFind, final int fromIndex) { final int len = len(a); if (len == 0 || fromIndex >= len) { return INDEX_NOT_FOUND; } for (int i = N.max(fromIndex, 0); i < len; i++) { if (a[i] == valueToFind) { return i; } } return INDEX_NOT_FOUND; } /** * Returns the index of the first occurrence of the specified value in the array. * * @param a the array to be searched * @param valueToFind the value to be searched for * @return the index of the first occurrence of the specified value in the array, * or -1 if the array is {@code null} or empty or does not contain the value */ public static int indexOf(final char[] a, final char valueToFind) { return indexOf(a, valueToFind, 0); } /** * Returns the index of the first occurrence of the specified value in the array, starting the search at the specified index. * * @param a the array to be searched * @param valueToFind the value to be searched for * @param fromIndex the index to start the search from * @return the index of the first occurrence of the specified value in the array, * or -1 if the array is {@code null} or empty or does not contain the value */ public static int indexOf(final char[] a, final char valueToFind, final int fromIndex) { final int len = len(a); if (len == 0 || fromIndex >= len) { return INDEX_NOT_FOUND; } for (int i = N.max(fromIndex, 0); i < len; i++) { if (a[i] == valueToFind) { return i; } } return INDEX_NOT_FOUND; } /** * Returns the index of the first occurrence of the specified value in the array. * * @param a the array to be searched * @param valueToFind the value to be searched for * @return the index of the first occurrence of the specified value in the array, * or -1 if the array is {@code null} or empty or does not contain the value */ public static int indexOf(final byte[] a, final byte valueToFind) { return indexOf(a, valueToFind, 0); } /** * Returns the index of the first occurrence of the specified value in the array, starting the search at the specified index. * * @param a the array to be searched * @param valueToFind the value to be searched for * @param fromIndex the index to start the search from * @return the index of the first occurrence of the specified value in the array, * or -1 if the array is {@code null} or empty or does not contain the value */ public static int indexOf(final byte[] a, final byte valueToFind, final int fromIndex) { final int len = len(a); if (len == 0 || fromIndex >= len) { return INDEX_NOT_FOUND; } for (int i = N.max(fromIndex, 0); i < len; i++) { if (a[i] == valueToFind) { return i; } } return INDEX_NOT_FOUND; } /** * Returns the index of the first occurrence of the specified value in the array. * * @param a the array to be searched * @param valueToFind the value to be searched for * @return the index of the first occurrence of the specified value in the array, * or -1 if the array is {@code null} or empty or does not contain the value */ public static int indexOf(final short[] a, final short valueToFind) { return indexOf(a, valueToFind, 0); } /** * Returns the index of the first occurrence of the specified value in the array, starting the search at the specified index. * * @param a the array to be searched * @param valueToFind the value to be searched for * @param fromIndex the index to start the search from * @return the index of the first occurrence of the specified value in the array, * or -1 if the array is {@code null} or empty or does not contain the value */ public static int indexOf(final short[] a, final short valueToFind, final int fromIndex) { final int len = len(a); if (len == 0 || fromIndex >= len) { return INDEX_NOT_FOUND; } for (int i = N.max(fromIndex, 0); i < len; i++) { if (a[i] == valueToFind) { return i; } } return INDEX_NOT_FOUND; } /** * Returns the index of the first occurrence of the specified value in the array. * * @param a the array to be searched * @param valueToFind the value to be searched for * @return the index of the first occurrence of the specified value in the array, * or -1 if the array is {@code null} or empty or does not contain the value */ public static int indexOf(final int[] a, final int valueToFind) { return indexOf(a, valueToFind, 0); } /** * Returns the index of the first occurrence of the specified value in the array, starting the search at the specified index. * * @param a the array to be searched * @param valueToFind the value to be searched for * @param fromIndex the index to start the search from * @return the index of the first occurrence of the specified value in the array, * or -1 if the array is {@code null} or empty or does not contain the value */ public static int indexOf(final int[] a, final int valueToFind, final int fromIndex) { final int len = len(a); if (len == 0 || fromIndex >= len) { return INDEX_NOT_FOUND; } for (int i = N.max(fromIndex, 0); i < len; i++) { if (a[i] == valueToFind) { return i; } } return INDEX_NOT_FOUND; } /** * Returns the index of the first occurrence of the specified value in the array. * * @param a the array to be searched * @param valueToFind the value to be searched for * @return the index of the first occurrence of the specified value in the array, * or -1 if the array is {@code null} or empty or does not contain the value */ public static int indexOf(final long[] a, final long valueToFind) { return indexOf(a, valueToFind, 0); } /** * Returns the index of the first occurrence of the specified value in the array, starting the search at the specified index. * * @param a the array to be searched * @param valueToFind the value to be searched for * @param fromIndex the index to start the search from * @return the index of the first occurrence of the specified value in the array, * or -1 if the array is {@code null} or empty or does not contain the value */ public static int indexOf(final long[] a, final long valueToFind, final int fromIndex) { final int len = len(a); if (len == 0 || fromIndex >= len) { return INDEX_NOT_FOUND; } for (int i = N.max(fromIndex, 0); i < len; i++) { if (a[i] == valueToFind) { return i; } } return INDEX_NOT_FOUND; } /** * Returns the index of the first occurrence of the specified value in the array. * * @param a the array to be searched * @param valueToFind the value to be searched for * @return the index of the first occurrence of the specified value in the array, * or -1 if the array is {@code null} or empty or does not contain the value */ public static int indexOf(final float[] a, final float valueToFind) { return indexOf(a, valueToFind, 0); } /** * Returns the index of the first occurrence of the specified value in the array, starting the search at the specified index. * * @param a the array to be searched * @param valueToFind the value to be searched for * @param fromIndex the index to start the search from * @return the index of the first occurrence of the specified value in the array, * or -1 if the array is {@code null} or empty or does not contain the value */ public static int indexOf(final float[] a, final float valueToFind, final int fromIndex) { final int len = len(a); if (len == 0 || fromIndex >= len) { return INDEX_NOT_FOUND; } for (int i = N.max(fromIndex, 0); i < len; i++) { if (Float.compare(a[i], valueToFind) == 0) { return i; } } return INDEX_NOT_FOUND; } /** * Returns the index of the first occurrence of the specified value in the array. * * @param a the array to be searched * @param valueToFind the value to be searched for * @return the index of the first occurrence of the specified value in the array, * or -1 if the array is {@code null} or empty or does not contain the value */ public static int indexOf(final double[] a, final double valueToFind) { return indexOf(a, valueToFind, 0); } /** * Returns the index of the first occurrence of the specified value in the array, starting the search at the specified index. * * @param a the array to be searched * @param valueToFind the value to be searched for * @param fromIndex the index to start the search from * @return the index of the first occurrence of the specified value in the array, * or -1 if the array is {@code null} or empty or does not contain the value */ public static int indexOf(final double[] a, final double valueToFind, final int fromIndex) { final int len = len(a); if (len == 0 || fromIndex >= len) { return INDEX_NOT_FOUND; } for (int i = N.max(fromIndex, 0); i < len; i++) { if (Double.compare(a[i], valueToFind) == 0) { return i; } } return INDEX_NOT_FOUND; } /** *

Finds the index of the given value within a given tolerance in the array. * This method will return the index of the first value which falls between the region * defined by valueToFind - tolerance and valueToFind + tolerance. * *

This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array. * * @param a the array to search through for the object, may be {@code null} * @param valueToFind * @param tolerance tolerance of the search * @return the index of the value within the array, * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input */ public static int indexOf(final double[] a, final double valueToFind, final double tolerance) { return indexOf(a, valueToFind, tolerance, 0); } /** *

Finds the index of the given value in the array starting at the given index. * This method will return the index of the first value which falls between the region * defined by valueToFind - tolerance and valueToFind + tolerance. * *

This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array. * *

A negative startIndex is treated as zero. A startIndex larger than the array * length will return {@link #INDEX_NOT_FOUND} ({@code -1}). * * @param a the array to search through for the object, may be {@code null} * @param valueToFind * @param tolerance tolerance of the search * @param fromIndex the index to start searching at * @return the index of the value within the array, * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input */ public static int indexOf(final double[] a, final double valueToFind, final double tolerance, final int fromIndex) { final int len = len(a); if (len == 0 || fromIndex >= len) { return INDEX_NOT_FOUND; } final double min = valueToFind - tolerance; final double max = valueToFind + tolerance; for (int i = fromIndex; i < len; i++) { if (a[i] >= min && a[i] <= max) { return i; } } return INDEX_NOT_FOUND; } /** * Returns the index of the first occurrence of the specified value in the array. * * @param a the array to be searched * @param valueToFind the value to be searched for * @return the index of the first occurrence of the specified value in the array, * or -1 if the array is {@code null} or empty or does not contain the value */ public static int indexOf(final Object[] a, final Object valueToFind) { return indexOf(a, valueToFind, 0); } /** * Returns the index of the first occurrence of the specified value in the array, starting the search at the specified index. * * @param a the array to be searched * @param valueToFind the value to be searched for * @param fromIndex the index to start the search from * @return the index of the first occurrence of the specified value in the array, * or -1 if the array is {@code null} or empty or does not contain */ public static int indexOf(final Object[] a, final Object valueToFind, final int fromIndex) { final int len = len(a); if (len == 0 || fromIndex >= len) { return INDEX_NOT_FOUND; } for (int i = N.max(fromIndex, 0); i < len; i++) { if (equals(a[i], valueToFind)) { return i; } } return INDEX_NOT_FOUND; } /** * Returns the index of the first occurrence of the specified value in the specified collection. * * @param c the collection to be searched * @param valueToFind the value to be searched for * @return the index of the first occurrence of the specified value in the collection, * or -1 if the collection is {@code null} or empty or does not contain the value */ public static int indexOf(final Collection c, final Object valueToFind) { return indexOf(c, valueToFind, 0); } /** * Returns the index of the first occurrence of the specified value in the specified collection, starting the search at the specified index. * * @param c the collection to be searched * @param valueToFind the value to be searched for * @param fromIndex the index to start the search from * @return the index of the first occurrence of the specified value in the collection, * or -1 if the collection is {@code null} or empty or does not contain the value */ public static int indexOf(final Collection c, final Object valueToFind, final int fromIndex) { final int len = size(c); if (len == 0 || fromIndex >= len) { return INDEX_NOT_FOUND; } if (c instanceof final List list && c instanceof RandomAccess) { for (int i = N.max(fromIndex, 0); i < len; i++) { if (equals(list.get(i), valueToFind)) { return i; } } } else { final Iterator iter = c.iterator(); int index = 0; if (fromIndex > 0) { while (index < fromIndex && iter.hasNext()) { iter.next(); index++; } } while (iter.hasNext()) { if (equals(iter.next(), valueToFind)) { return index; } index++; } } return INDEX_NOT_FOUND; } /** * Returns the index of the first occurrence of the specified value in the given iterator. * * @param iter The iterator to be searched. * @param valueToFind The value to find in the iterator. * @return The index of the first occurrence of the specified value in the iterator, or -1 if the value is not found. * @throws ArithmeticException If the found {@code index} overflows an int. * @see Iterators#indexOf(Iterator, Object) */ public static int indexOf(final Iterator iter, final Object valueToFind) throws ArithmeticException { return indexOf(iter, valueToFind, 0); } /** * Returns the index of the first occurrence of the specified value in the given iterator, starting the search from the specified index. * * @param iter The iterator to be searched. * @param valueToFind The value to find in the iterator. * @param fromIndex The index to start the search from. * @return The index of the first occurrence of the specified value in the iterator, or -1 if the value is not found. * @throws ArithmeticException If the found {@code index} overflows an int. * @see Iterators#indexOf(Iterator, Object, long) */ public static int indexOf(final Iterator iter, final Object valueToFind, final int fromIndex) throws ArithmeticException { if (iter == null) { return INDEX_NOT_FOUND; } return Numbers.toIntExact(Iterators.indexOf(iter, valueToFind, fromIndex)); } /** * Returns the starting position of the first occurrence of the specified sublist within the source list. * * @param sourceList the list to search within * @param subListToFind the sublist to search for * @return the starting position of the first occurrence of the specified sublist, or -1 if there is no such occurrence * @see java.util.Collections#indexOfSubList(List, List) */ public static int indexOfSubList(final List sourceList, final List subListToFind) { if (isEmpty(sourceList) || isEmpty(subListToFind)) { return INDEX_NOT_FOUND; } return Collections.indexOfSubList(sourceList, subListToFind); } /** * Returns the starting position of the first occurrence of the specified sublist within the source list, starting the search at the specified index. * * @param sourceList the list to search within * @param subListToFind the sublist to search for * @param fromIndex the index to start the search from * @return the starting position of the first occurrence of the specified sublist, or -1 if there is no such occurrence * @throws IndexOutOfBoundsException if the starting index is out of range * @see Index#ofSubList(List, int, List) */ public static int indexOfSubList(final List sourceList, final List subListToFind, final int fromIndex) { if (isEmpty(sourceList) || isEmpty(subListToFind)) { return INDEX_NOT_FOUND; } return Index.ofSubList(sourceList, fromIndex, subListToFind).orElse(INDEX_NOT_FOUND); } /** * Returns the index of the first occurrence of the specified string in the array, ignoring case considerations. * * @param a the array to search within * @param valueToFind the string to search for * @return the index of the first occurrence of the specified string, or -1 if there is no such occurrence */ public static int indexOfIgnoreCase(final String[] a, final String valueToFind) { return indexOfIgnoreCase(a, valueToFind, 0); } /** * Returns the index of the first occurrence of the specified string in the array, ignoring case considerations, starting the search at the specified index. * * @param a the array to search within * @param valueToFind the string to search for * @param fromIndex the index to start the search from * @return the index of the first occurrence of the specified string, or -1 if there is no such occurrence */ public static int indexOfIgnoreCase(final String[] a, final String valueToFind, final int fromIndex) { final int len = len(a); if (len == 0 || fromIndex >= len) { return INDEX_NOT_FOUND; } for (int i = fromIndex; i < len; i++) { if (equalsIgnoreCase(a[i], valueToFind)) { return i; } } return INDEX_NOT_FOUND; } /** * Returns the index of the last occurrence of the specified value in the array. * * @param a the array to search within * @param valueToFind the value to search for * @return the index of the last occurrence of the specified value, or -1 if there is no such occurrence */ public static int lastIndexOf(final boolean[] a, final boolean valueToFind) { return lastIndexOf(a, valueToFind, a.length - 1); } /** * Returns the index of the last occurrence of the specified value in the array, starting the search backwards from the specified index. * * @param a the array to search within * @param valueToFind the value to search for * @param startIndexFromBack the index to start the search from * @return the index of the last occurrence of the specified value, or -1 if there is no such occurrence */ public static int lastIndexOf(final boolean[] a, final boolean valueToFind, final int startIndexFromBack) { final int len = len(a); if (len == 0 || startIndexFromBack < 0) { return INDEX_NOT_FOUND; } for (int i = N.min(startIndexFromBack, len - 1); i >= 0; i--) { if (a[i] == valueToFind) { return i; } } return INDEX_NOT_FOUND; } /** * Returns the index of the last occurrence of the specified value in the array. * * @param a the array to search within * @param valueToFind the value to search for * @return the index of the last occurrence of the specified value, or -1 if there is no such occurrence */ public static int lastIndexOf(final char[] a, final char valueToFind) { if (isEmpty(a)) { return INDEX_NOT_FOUND; } return lastIndexOf(a, valueToFind, a.length - 1); } /** * Returns the index of the last occurrence of the specified value in the array, starting the search backwards from the specified index. * * @param a the array to search within * @param valueToFind the value to search for * @param startIndexFromBack the index to start the search from * @return the index of the last occurrence of the specified value, or -1 if there is no such occurrence */ public static int lastIndexOf(final char[] a, final char valueToFind, final int startIndexFromBack) { final int len = len(a); if (len == 0 || startIndexFromBack < 0) { return INDEX_NOT_FOUND; } for (int i = N.min(startIndexFromBack, len - 1); i >= 0; i--) { if (a[i] == valueToFind) { return i; } } return INDEX_NOT_FOUND; } /** * Returns the index of the last occurrence of the specified value in the array. * * @param a the array to search within * @param valueToFind the value to search for * @return the index of the last occurrence of the specified value, or -1 if there is no such occurrence */ public static int lastIndexOf(final byte[] a, final byte valueToFind) { if (isEmpty(a)) { return INDEX_NOT_FOUND; } return lastIndexOf(a, valueToFind, a.length - 1); } /** * Returns the index of the last occurrence of the specified value in the array, starting the search backwards from the specified index. * * @param a the array to search within * @param valueToFind the value to search for * @param startIndexFromBack the index to start the search from * @return the index of the last occurrence of the specified value, or -1 if there is no such occurrence */ public static int lastIndexOf(final byte[] a, final byte valueToFind, final int startIndexFromBack) { final int len = len(a); if (len == 0 || startIndexFromBack < 0) { return INDEX_NOT_FOUND; } for (int i = N.min(startIndexFromBack, len - 1); i >= 0; i--) { if (a[i] == valueToFind) { return i; } } return INDEX_NOT_FOUND; } /** * Returns the index of the last occurrence of the specified value in the array. * * @param a the array to search within * @param valueToFind the value to search for * @return the index of the last occurrence of the specified value, or -1 if there is no such occurrence */ public static int lastIndexOf(final short[] a, final short valueToFind) { if (isEmpty(a)) { return INDEX_NOT_FOUND; } return lastIndexOf(a, valueToFind, a.length - 1); } /** * Returns the index of the last occurrence of the specified value in the array, starting the search backwards from the specified index. * * @param a the array to search within * @param valueToFind the value to search for * @param startIndexFromBack the index to start the search from * @return the index of the last occurrence of the specified value, or -1 if there is no such occurrence */ public static int lastIndexOf(final short[] a, final short valueToFind, final int startIndexFromBack) { final int len = len(a); if (len == 0 || startIndexFromBack < 0) { return INDEX_NOT_FOUND; } for (int i = N.min(startIndexFromBack, len - 1); i >= 0; i--) { if (a[i] == valueToFind) { return i; } } return INDEX_NOT_FOUND; } /** * Returns the index of the last occurrence of the specified value in the array. * * @param a the array to search within * @param valueToFind the value to search for * @return the index of the last occurrence of the specified value, or -1 if there is no such occurrence */ public static int lastIndexOf(final int[] a, final int valueToFind) { if (isEmpty(a)) { return INDEX_NOT_FOUND; } return lastIndexOf(a, valueToFind, a.length - 1); } /** * Returns the index of the last occurrence of the specified value in the array, starting the search backwards from the specified index. * * @param a the array to search within * @param valueToFind the value to search for * @param startIndexFromBack the index to start the search from * @return the index of the last occurrence of the specified value, or -1 if there is no such occurrence */ public static int lastIndexOf(final int[] a, final int valueToFind, final int startIndexFromBack) { final int len = len(a); if (len == 0 || startIndexFromBack < 0) { return INDEX_NOT_FOUND; } for (int i = N.min(startIndexFromBack, len - 1); i >= 0; i--) { if (a[i] == valueToFind) { return i; } } return INDEX_NOT_FOUND; } /** * Returns the index of the last occurrence of the specified value in the array. * * @param a the array to search within * @param valueToFind the value to search for * @return the index of the last occurrence of the specified value, or -1 if there is no such occurrence */ public static int lastIndexOf(final long[] a, final long valueToFind) { if (isEmpty(a)) { return INDEX_NOT_FOUND; } return lastIndexOf(a, valueToFind, a.length - 1); } /** * Returns the index of the last occurrence of the specified value in the array, starting the search backwards from the specified index. * * @param a the array to search within * @param valueToFind the value to search for * @param startIndexFromBack the index to start the search from * @return the index of the last occurrence of the specified value, or -1 if there is no such occurrence */ public static int lastIndexOf(final long[] a, final long valueToFind, final int startIndexFromBack) { final int len = len(a); if (len == 0 || startIndexFromBack < 0) { return INDEX_NOT_FOUND; } for (int i = N.min(startIndexFromBack, len - 1); i >= 0; i--) { if (a[i] == valueToFind) { return i; } } return INDEX_NOT_FOUND; } /** * Returns the index of the last occurrence of the specified value in the array. * * @param a the array to search within * @param valueToFind the value to search for * @return the index of the last occurrence of the specified value, or -1 if there is no such occurrence */ public static int lastIndexOf(final float[] a, final float valueToFind) { if (isEmpty(a)) { return INDEX_NOT_FOUND; } return lastIndexOf(a, valueToFind, a.length - 1); } /** * Returns the index of the last occurrence of the specified value in the array, starting the search backwards from the specified index. * * @param a the array to search within * @param valueToFind the value to search for * @param startIndexFromBack the index to start the search from * @return the index of the last occurrence of the specified value, or -1 if there is no such occurrence */ public static int lastIndexOf(final float[] a, final float valueToFind, final int startIndexFromBack) { final int len = len(a); if (len == 0 || startIndexFromBack < 0) { return INDEX_NOT_FOUND; } for (int i = N.min(startIndexFromBack, len - 1); i >= 0; i--) { if (Float.compare(a[i], valueToFind) == 0) { return i; } } return INDEX_NOT_FOUND; } /** * Returns the index of the last occurrence of the specified value in the array. * * @param a the array to search within * @param valueToFind the value to search for * @return the index of the last occurrence of the specified value, or -1 if there is no such occurrence */ public static int lastIndexOf(final double[] a, final double valueToFind) { if (isEmpty(a)) { return INDEX_NOT_FOUND; } return lastIndexOf(a, valueToFind, a.length - 1); } /** * Returns the index of the last occurrence of the specified value in the array, starting the search backwards from the specified index. * * @param a the array to search within * @param valueToFind the value to search for * @param startIndexFromBack the index to start the search from * @return the index of the last occurrence of the specified value, or -1 if there is no such occurrence */ public static int lastIndexOf(final double[] a, final double valueToFind, final int startIndexFromBack) { final int len = len(a); if (len == 0 || startIndexFromBack < 0) { return INDEX_NOT_FOUND; } for (int i = N.min(startIndexFromBack, len - 1); i >= 0; i--) { if (Double.compare(a[i], valueToFind) == 0) { return i; } } return INDEX_NOT_FOUND; } /** *

Finds the last index of the given value within a given tolerance in the array. * This method will return the index of the last value which falls between the region * defined by valueToFind - tolerance and valueToFind + tolerance. * *

This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array. * * @param a the array to search through for the object, may be {@code null} * @param valueToFind * @param tolerance tolerance of the search * @return the index of the value within the array, * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input */ public static int lastIndexOf(final double[] a, final double valueToFind, final double tolerance) { return lastIndexOf(a, valueToFind, tolerance, 0); } /** *

Finds the last index of the given value in the array starting at the given index. * This method will return the index of the last value which falls between the region * defined by valueToFind - tolerance and valueToFind + tolerance. * *

This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array. * *

A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the * array length will search from the end of the array. * * @param a the array to traverse for looking for the object, may be {@code null} * @param valueToFind * @param tolerance search for value within plus/minus this amount * @param startIndexFromBack the start index to traverse backwards from * @return the last index of the value within the array, * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input */ public static int lastIndexOf(final double[] a, final double valueToFind, final double tolerance, final int startIndexFromBack) { final int len = len(a); if (len == 0 || startIndexFromBack < 0) { return INDEX_NOT_FOUND; } final double min = valueToFind - tolerance; final double max = valueToFind + tolerance; for (int i = N.min(startIndexFromBack, len - 1); i >= 0; i--) { if (a[i] >= min && a[i] <= max) { return i; } } return INDEX_NOT_FOUND; } /** * Returns the index of the last occurrence of the specified value in the array. * * @param a the array to search within * @param valueToFind the value to search for * @return the index of the last occurrence of the specified value, or -1 if there is no such occurrence */ public static int lastIndexOf(final Object[] a, final Object valueToFind) { if (isEmpty(a)) { return INDEX_NOT_FOUND; } return lastIndexOf(a, valueToFind, a.length - 1); } /** * Returns the index of the last occurrence of the specified value in the array, starting the search backwards from the specified index. * * @param a the array to search within * @param valueToFind the value to search for * @param startIndexFromBack the index to start the search from * @return the index of the last occurrence of the specified value, or -1 if there is no such occurrence */ public static int lastIndexOf(final Object[] a, final Object valueToFind, final int startIndexFromBack) { final int len = len(a); if (len == 0 || startIndexFromBack < 0) { return INDEX_NOT_FOUND; } for (int i = N.min(startIndexFromBack, len - 1); i >= 0; i--) { if (equals(a[i], valueToFind)) { return i; } } return INDEX_NOT_FOUND; } /** * Returns the index of the last occurrence of the specified value in the specified collection. * * @param c the collection to search within * @param valueToFind the value to search for * @return the index of the last occurrence of the specified value, or -1 if there is no such occurrence */ public static int lastIndexOf(final Collection c, final Object valueToFind) { if (isEmpty(c)) { return INDEX_NOT_FOUND; } return lastIndexOf(c, valueToFind, c.size() - 1); } /** * Returns the index of the last occurrence of the specified value in the specified collection, starting the search backwards from the specified index. * * @param c the collection to search within * @param valueToFind the value to search for * @param startIndexFromBack the index to start the search from * @return the index of the last occurrence of the specified value, or -1 if there is no such occurrence */ public static int lastIndexOf(final Collection c, final Object valueToFind, final int startIndexFromBack) { final int size = size(c); if (size == 0 || startIndexFromBack < 0) { return INDEX_NOT_FOUND; } if (c instanceof List && c instanceof RandomAccess) { final List list = (List) c; for (int i = N.min(startIndexFromBack, size - 1); i >= 0; i--) { if (equals(list.get(i), valueToFind)) { return i; } } return INDEX_NOT_FOUND; } final Iterator descendingIterator = getDescendingIteratorIfPossible(c); if (descendingIterator != null) { for (int i = size - 1; descendingIterator.hasNext(); i--) { if (i > startIndexFromBack) { descendingIterator.next(); } else if (equals(descendingIterator.next(), valueToFind)) { return i; } } return INDEX_NOT_FOUND; } final Object[] a = c.toArray(); return lastIndexOf(a, valueToFind, startIndexFromBack); } /** * Returns the index of the last occurrence of the specified sublist in the source list. * * @param sourceList the list to search within * @param subListToFind the sublist to search for * @return the index of the last occurrence of the specified sublist, or -1 if there is no such occurrence */ public static int lastIndexOfSubList(final List sourceList, final List subListToFind) { if (isEmpty(sourceList) || isEmpty(subListToFind)) { return INDEX_NOT_FOUND; } return Collections.lastIndexOfSubList(sourceList, subListToFind); } /** * Returns the index of the last occurrence of the specified sublist in the source list, starting the search backwards from the specified index. * * @param sourceList the list to search within * @param subListToFind the sublist to search for * @param startIndexFromBack the index to start the search from. * @return the index of the last occurrence of the specified sublist, or -1 if there is no such occurrence * @see Index#lastOfSubList(List, int, List) */ public static int lastIndexOfSubList(final List sourceList, final List subListToFind, final int startIndexFromBack) { if (isEmpty(sourceList) || isEmpty(subListToFind)) { return INDEX_NOT_FOUND; } return Index.lastOfSubList(sourceList, startIndexFromBack, subListToFind).orElse(INDEX_NOT_FOUND); } /** * Returns the index of the last occurrence of the specified string in the array, ignoring case considerations. * * @param a the array to search within * @param valueToFind the string to search for * @return the index of the last occurrence of the specified string, or -1 if there is no such occurrence */ public static int lastIndexOfIgnoreCase(final String[] a, final String valueToFind) { if (isEmpty(a)) { return INDEX_NOT_FOUND; } return lastIndexOfIgnoreCase(a, valueToFind, a.length - 1); } /** * Returns the index of the last occurrence of the specified string in the array, ignoring case considerations, starting the search backwards from the specified index. * * @param a the array to search within * @param valueToFind the string to search for * @param startIndexFromBack the index to start the search from * @return the index of the last occurrence of the specified string, or -1 if there is no such occurrence */ public static int lastIndexOfIgnoreCase(final String[] a, final String valueToFind, final int startIndexFromBack) { final int len = len(a); if (len == 0 || startIndexFromBack < 0) { return INDEX_NOT_FOUND; } for (int i = N.min(startIndexFromBack, len - 1); i >= 0; i--) { if (equalsIgnoreCase(a[i], valueToFind)) { return i; } } return INDEX_NOT_FOUND; } /** * Finds the index of the first element in the array that matches the given predicate. * * @param the type of elements in the array * @param a the array to search within * @param predicate the predicate to apply to elements of the array * @return an OptionalInt containing the index of the first matching element, or an empty OptionalInt if no match is found */ public static OptionalInt findFirstIndex(final T[] a, final Predicate predicate) { if (isEmpty(a)) { return OptionalInt.empty(); } for (int len = a.length, i = 0; i < len; i++) { if (predicate.test(a[i])) { return OptionalInt.of(i); } } return OptionalInt.empty(); } /** * Finds the index of the first element in the array that matches the given predicate. * * @param the type of elements in the array * @param the type of the second argument to the predicate * @param a the array to search within * @param u the second argument to the predicate * @param predicate the predicate to apply to elements of the array * @return an OptionalInt containing the index of the first matching element, or an empty OptionalInt if no match is found */ public static OptionalInt findFirstIndex(final T[] a, final U u, final BiPredicate predicate) { if (isEmpty(a)) { return OptionalInt.empty(); } for (int len = a.length, i = 0; i < len; i++) { if (predicate.test(a[i], u)) { return OptionalInt.of(i); } } return OptionalInt.empty(); } /** * Finds the index of the first element in the collection that matches the given predicate. * * @param the type of elements in the collection * @param c the collection to search within * @param predicate the predicate to apply to elements of the collection * @return an OptionalInt containing the index of the first matching element, or an empty OptionalInt if no match is found */ public static OptionalInt findFirstIndex(final Collection c, final Predicate predicate) { if (isEmpty(c)) { return OptionalInt.empty(); } int idx = 0; for (final T e : c) { if (predicate.test(e)) { return OptionalInt.of(idx); } idx++; } return OptionalInt.empty(); } /** * Finds the index of the first element in the collection that matches the given predicate. * * @param the type of elements in the collection * @param the type of the second argument to the predicate * @param c the collection to search within * @param u the second argument to the predicate * @param predicate the predicate to apply to elements of the collection * @return an OptionalInt containing the index of the first matching element, or an empty OptionalInt if no match is found */ public static OptionalInt findFirstIndex(final Collection c, final U u, final BiPredicate predicate) { if (isEmpty(c)) { return OptionalInt.empty(); } int idx = 0; for (final T e : c) { if (predicate.test(e, u)) { return OptionalInt.of(idx); } idx++; } return OptionalInt.empty(); } /** * Finds the index of the last element in the array that matches the given predicate. * * @param the type of elements in the array * @param a the array to search within * @param predicate the predicate to apply to elements of the array * @return an OptionalInt containing the index of the last matching element, or an empty OptionalInt if no match is found */ public static OptionalInt findLastIndex(final T[] a, final Predicate predicate) { if (isEmpty(a)) { return OptionalInt.empty(); } for (int i = a.length - 1; i >= 0; i--) { if (predicate.test(a[i])) { return OptionalInt.of(i); } } return OptionalInt.empty(); } /** * Finds the index of the last element in the array that matches the given predicate. * * @param the type of elements in the array * @param the type of the second argument to the predicate * @param a the array to search within * @param u the second argument to the predicate * @param predicate the predicate to apply to elements of the array * @return an OptionalInt containing the index of the last matching element, or an empty OptionalInt if no match is found */ public static OptionalInt findLastIndex(final T[] a, final U u, final BiPredicate predicate) { if (isEmpty(a)) { return OptionalInt.empty(); } for (int i = a.length - 1; i >= 0; i--) { if (predicate.test(a[i], u)) { return OptionalInt.of(i); } } return OptionalInt.empty(); } /** * Finds the index of the last element in the collection that matches the given predicate. * * @param the type of elements in the collection * @param c the collection to search within * @param predicate the predicate to apply to elements of the collection * @return an OptionalInt containing the index of the last matching element, or an empty OptionalInt if no match is found */ public static OptionalInt findLastIndex(final Collection c, final Predicate predicate) { if (isEmpty(c)) { return OptionalInt.empty(); } final int size = c.size(); if (c instanceof List && c instanceof RandomAccess) { final List list = (List) c; for (int i = size - 1; i >= 0; i--) { if (predicate.test(list.get(i))) { return OptionalInt.of(i); } } return OptionalInt.empty(); } final Iterator descendingIterator = getDescendingIteratorIfPossible(c); if (descendingIterator != null) { for (int i = size - 1; descendingIterator.hasNext(); i--) { if (predicate.test(descendingIterator.next())) { return OptionalInt.of(i); } } return OptionalInt.empty(); } final T[] a = (T[]) c.toArray(); for (int i = a.length - 1; i >= 0; i--) { if (predicate.test(a[i])) { return OptionalInt.of(i); } } return OptionalInt.empty(); } /** * Finds the index of the last element in the collection that matches the given predicate. * * @param the type of elements in the collection * @param the type of the second argument to the predicate * @param c the collection to search within * @param u the second argument to the predicate * @param predicate the predicate to apply to elements of the collection * @return an OptionalInt containing the index of the last matching element, or an empty OptionalInt if no match is found */ public static OptionalInt findLastIndex(final Collection c, final U u, final BiPredicate predicate) { if (isEmpty(c)) { return OptionalInt.empty(); } final Predicate predicate2 = t -> predicate.test(t, u); return findLastIndex(c, predicate2); } /** * Returns the indices of all minimum elements in the specified array. * * @param the type of elements in the array * @param a the array to search within * @return an array of indices of all minimum elements. An empty array if the input array is empty. */ public static > int[] indicesOfAllMin(final T[] a) { return indicesOfAllMin(a, NATURAL_COMPARATOR); } /** * Returns the indices of all minimum elements in the specified array using the provided comparator. * * @param the type of elements in the array * @param a the array to search within * @param cmp the comparator to compare elements of the array * @return an array of indices of all minimum elements. An empty array if the input array is empty. */ public static int[] indicesOfAllMin(final T[] a, Comparator cmp) { if (isEmpty(a)) { return EMPTY_INT_ARRAY; } cmp = cmp == null ? (Comparator) NULL_MAX_COMPARATOR : cmp; final IntList result = new IntList(); final int len = len(a); T candidate = a[0]; int cp = 0; result.add(0); for (int idx = 1; idx < len; idx++) { cp = cmp.compare(a[idx], candidate); if (cp == 0) { result.add(idx); } else if (cp < 0) { result.clear(); result.add(idx); candidate = a[idx]; } } return result.toArray(); } /** * Returns the indices of all minimum elements in the specified collection. * * @param the type of elements in the collection * @param c the collection to search within * @return an array of indices of all minimum elements. An empty array if the input collection is empty. */ public static > int[] indicesOfAllMin(final Collection c) throws IllegalArgumentException { return indicesOfAllMin(c, NATURAL_COMPARATOR); } /** * Returns the indices of all minimum elements in the specified collection using the provided comparator. * * @param the type of elements in the collection * @param c the collection to search within * @param cmp the comparator to compare elements of the collection * @return an array of indices of all minimum elements. An empty array if the input collection is empty. */ public static int[] indicesOfAllMin(final Collection c, Comparator cmp) throws IllegalArgumentException { if (isEmpty(c)) { return EMPTY_INT_ARRAY; } cmp = cmp == null ? (Comparator) NULL_MAX_COMPARATOR : cmp; final IntList result = new IntList(); final Iterator iter = c.iterator(); T candidate = iter.next(); T next = null; int cp = 0; int idx = 0; result.add(idx++); while (iter.hasNext()) { next = iter.next(); cp = cmp.compare(next, candidate); if (cp == 0) { result.add(idx); } else if (cp < 0) { result.clear(); result.add(idx); candidate = next; } idx++; } return result.toArray(); } /** * Returns the indices of all maximum elements in the specified array. * * @param the type of elements in the array * @param a the array to search within * @return an array of indices of all maximum elements. An empty array if the input array is empty. */ public static > int[] indicesOfAllMax(final T[] a) throws IllegalArgumentException { return indicesOfAllMax(a, NATURAL_COMPARATOR); } /** * Returns the indices of all maximum elements in the specified array using the provided comparator. * * @param the type of elements in the array * @param a the array to search within * @param cmp the comparator to compare elements of the array * @return an array of indices of all maximum elements. An empty array if the input array is empty. */ public static int[] indicesOfAllMax(final T[] a, Comparator cmp) throws IllegalArgumentException { if (isEmpty(a)) { return EMPTY_INT_ARRAY; } cmp = cmp == null ? (Comparator) NULL_MIN_COMPARATOR : cmp; final IntList result = new IntList(); final int len = len(a); T candidate = a[0]; int cp = 0; result.add(0); for (int idx = 1; idx < len; idx++) { cp = cmp.compare(a[idx], candidate); if (cp == 0) { result.add(idx); } else if (cp > 0) { result.clear(); result.add(idx); candidate = a[idx]; } } return result.toArray(); } /** * Returns the indices of all maximum elements in the specified collection. * * @param the type of elements in the collection * @param c the collection to search within * @return an array of indices of all maximum elements. An empty array if the input collection is empty. */ public static > int[] indicesOfAllMax(final Collection c) throws IllegalArgumentException { return indicesOfAllMax(c, NATURAL_COMPARATOR); } /** * Returns the indices of all maximum elements in the specified collection using the provided comparator. * * @param the type of elements in the collection * @param c the collection to search within * @param cmp the comparator to compare elements of the collection * @return an array of indices of all maximum elements. An empty array if the input collection is empty. */ public static int[] indicesOfAllMax(final Collection c, Comparator cmp) throws IllegalArgumentException { if (isEmpty(c)) { return EMPTY_INT_ARRAY; } cmp = cmp == null ? (Comparator) NULL_MIN_COMPARATOR : cmp; final IntList result = new IntList(); final Iterator iter = c.iterator(); T candidate = iter.next(); T next = null; int cp = 0; int idx = 0; result.add(idx++); while (iter.hasNext()) { next = iter.next(); cp = cmp.compare(next, candidate); if (cp == 0) { result.add(idx); } else if (cp > 0) { result.clear(); result.add(idx); candidate = next; } idx++; } return result.toArray(); } /** * Returns the indices of all occurrences of the specified value in the given array. * * @param a the array to search within * @param valueToFind the value to find in the array * @return an array of indices of all occurrences of the specified value */ public static int[] indicesOfAll(final Object[] a, final Object valueToFind) { return indicesOfAll(a, valueToFind, 0); } /** * Returns the indices of all occurrences of the specified value in the given array, starting the search from the specified index. * * @param a the array to search within * @param valueToFind the value to find in the array * @param startIndex the index to start the search from * @return an array of indices of all occurrences of the specified value */ public static int[] indicesOfAll(final Object[] a, final Object valueToFind, final int startIndex) { final int len = len(a); if (len == 0 || startIndex >= len) { return EMPTY_INT_ARRAY; } final IntList result = new IntList(); for (int idx = N.max(startIndex, 0); idx < len; idx++) { if (equals(a[idx], valueToFind)) { result.add(idx); } } return result.toArray(); } /** * Returns the indices of all occurrences of the specified value in the specified collection. * * @param c the collection to search within * @param valueToFind the value to find in the collection * @return an array of indices of all occurrences of the specified value */ public static int[] indicesOfAll(final Collection c, final Object valueToFind) { return indicesOfAll(c, valueToFind, 0); } /** * Returns the indices of all occurrences of the specified value in the specified collection, starting the search from the specified index. * * @param c the collection to search within * @param valueToFind the value to find in the collection * @param startIndex the index to start the search from * @return an array of indices of all occurrences of the specified value */ public static int[] indicesOfAll(final Collection c, final Object valueToFind, final int startIndex) { final int size = size(c); if (size == 0 || startIndex >= size) { return EMPTY_INT_ARRAY; } final IntList result = new IntList(); if (c instanceof final List list && c instanceof RandomAccess) { for (int idx = N.max(startIndex, 0); idx < size; idx++) { if (equals(list.get(idx), valueToFind)) { result.add(idx); } } } else { final Iterator iter = c.iterator(); int idx = 0; while (idx < startIndex) { iter.next(); idx++; } while (iter.hasNext()) { if (equals(iter.next(), valueToFind)) { result.add(idx); } idx++; } } return result.toArray(); } /** * Returns the indices of all elements in the specified array that match the given predicate. * * @param the type of elements in the array * @param a the array to search within * @param predicate the predicate to apply to elements of the array * @return an array of indices of all elements that match the predicate. An empty array if the input array is empty. */ public static int[] indicesOfAll(final T[] a, final Predicate predicate) { return indicesOfAll(a, predicate, 0); } /** * Returns the indices of all elements in the specified array that match the given predicate, starting the search from the specified index. * * @param the type of elements in the array * @param a the array to search within * @param predicate the predicate to apply to elements of the array * @param startIndex the index to start the search from * @return an array of indices of all elements that match the predicate. An empty array if the input array is empty. */ public static int[] indicesOfAll(final T[] a, final Predicate predicate, final int startIndex) { final int len = len(a); if (len == 0 || startIndex >= len) { return EMPTY_INT_ARRAY; } final IntList result = new IntList(); for (int idx = N.max(startIndex, 0); idx < len; idx++) { if (predicate.test(a[idx])) { result.add(idx); } } return result.toArray(); } /** * Returns the indices of all elements in the specified collection that match the given predicate. * * @param the type of elements in the collection * @param c the collection to search within * @param predicate the predicate to apply to elements of the collection * @return an array of indices of all elements that match the predicate. An empty array if the input collection is empty. */ public static int[] indicesOfAll(final Collection c, final Predicate predicate) { return indicesOfAll(c, predicate, 0); } /** * Returns the indices of all elements in the specified collection that match the given predicate, starting the search from the specified index. * * @param the type of elements in the collection * @param c the collection to search within * @param predicate the predicate to apply to elements of the collection * @param fromIndex the index to start the search from * @return an array of indices of all elements that match the predicate. An empty array if the input collection is empty. */ public static int[] indicesOfAll(final Collection c, final Predicate predicate, final int fromIndex) { final int size = size(c); if (size == 0 || fromIndex >= size) { return EMPTY_INT_ARRAY; } final IntList result = new IntList(); if (c instanceof final List list && c instanceof RandomAccess) { for (int i = N.max(fromIndex, 0); i < size; i++) { if (predicate.test(list.get(i))) { result.add(i); } } } else { final Iterator iter = c.iterator(); int idx = 0; while (idx < fromIndex) { iter.next(); idx++; } while (iter.hasNext()) { if (predicate.test(iter.next())) { result.add(idx); } idx++; } } return result.toArray(); } // Boolean utilities //-------------------------------------------------------------------------- // @Beta // public static boolean isNullOrFalse(final Boolean bool) { // if (bool == null) { // return true; // } // // return Boolean.FALSE.equals(bool); // } // // @Beta // public static boolean isNullOrTrue(final Boolean bool) { // if (bool == null) { // return true; // } // // return Boolean.TRUE.equals(bool); // } /** * Returns {@code true} if the specified {@code boolean} is {@code Boolean.TRUE}, not {@code null} or {@code Boolean.FALSE}. * * @param bool the Boolean to check * @return {@code true} if the Boolean is {@code Boolean.TRUE}, {@code false} otherwise */ @Beta public static boolean isTrue(final Boolean bool) { return Boolean.TRUE.equals(bool); } /** * Returns {@code true} if the specified {@code boolean} is {@code null} or {@code Boolean.FALSE}. * * @param bool the Boolean to check * @return {@code true} if the Boolean is {@code null} or {@code Boolean.FALSE}, {@code false} otherwise */ @Beta public static boolean isNotTrue(final Boolean bool) { return bool == null || !bool; } /** * Returns {@code true} if the specified {@code boolean} is {@code Boolean.FALSE}, not {@code null} or {@code Boolean.TRUE}. * * @param bool the Boolean to check * @return {@code true} if the Boolean is {@code Boolean.FALSE}, {@code false} otherwise */ @Beta public static boolean isFalse(final Boolean bool) { return Boolean.FALSE.equals(bool); } /** * Returns {@code true} if the specified {@code boolean} is {@code null} or {@code Boolean.TRUE}. * * @param bool the Boolean to check * @return {@code true} if the Boolean is {@code null} or {@code Boolean.TRUE}, {@code false} otherwise */ @Beta public static boolean isNotFalse(final Boolean bool) { return bool == null || bool; } /** *

Note: copied from Apache commons Lang under Apache license v2.0

* *

Negates the specified boolean.

* *

If {@code null} is passed in, {@code null} will be returned.

* *

NOTE: This returns {@code null} and will throw a NullPointerException if outboxed to a boolean.

* *
     *   BooleanUtils.negate(Boolean.TRUE)  = Boolean.FALSE;
     *   BooleanUtils.negate(Boolean.FALSE) = Boolean.TRUE;
     *   BooleanUtils.negate(null)          = null;
     * 
* * @param bool the Boolean to negate, which may be null * @return the negated Boolean, or {@code null} if {@code null} input */ @SuppressFBWarnings("NP_BOOLEAN_RETURN_NULL") @MayReturnNull @Beta public static Boolean negate(final Boolean bool) { if (bool == null) { return null; //NOSONAR } return bool ? Boolean.FALSE : Boolean.TRUE; } /** * Negates all elements in the specified boolean array. * * @param a the boolean array to negate */ @Beta public static void negate(final boolean[] a) { if (isEmpty(a)) { return; } negate(a, 0, a.length); } /** * Negates all elements in the specified range of the boolean array. * * @param a the boolean array to negate * @param fromIndex the starting index (inclusive) of the range to negate * @param toIndex the ending index (exclusive) of the range to negate * @throws IndexOutOfBoundsException if the specified range is out of bounds */ @Beta public static void negate(final boolean[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { checkFromToIndex(fromIndex, toIndex, len(a)); // NOSONAR if (fromIndex == toIndex) { return; } for (int i = fromIndex; i < toIndex; i++) { a[i] = !a[i]; } } // /** // * Returns {@code 0} if the specified {@code bool} is {@code null} or {@code false}, otherwise {@code 1} is returned. // * // * @param bool // * @return // */ // @Beta // public static int toIntOneZero(final Boolean bool) { // if (bool == null) { // return 0; // } // // return bool.booleanValue() ? 1 : 0; // } // // /** // * Returns {@code 'N'} if the specified {@code bool} is {@code null} or {@code false}, otherwise {@code 'Y'} is returned. // * // * // * @param bool // * @return // */ // @Beta // public static char toCharYN(final Boolean bool) { // if (bool == null) { // return 'N'; // } // // return bool.booleanValue() ? 'Y' : 'N'; // } // // /** // * Returns {@code "no"} if the specified {@code bool} is {@code null} or {@code false}, otherwise {@code "yes"} is returned. // * // * // * @param bool // * @return // */ // @Beta // public static String toStringYesNo(final Boolean bool) { // if (bool == null) { // return "no"; // } // // return bool.booleanValue() ? "yes" : "no"; // } // /** // * Add it because {@code Comparator.reversed()} doesn't work well in some scenarios. // * // * @param // * @param cmp // * @return // * @see Collections#reverseOrder(Comparator) // * @see Comparators#reverseOrder(Comparator) // * @deprecated replaced by {@code Comparators.reverseOrder(Comparator)} // */ // @Deprecated // @Beta // public static Comparator reverseOrder(final Comparator cmp) { // return Comparators.reverseOrder(cmp); // } /** * Returns an unmodifiable view of the specified collection, or an immutable/unmodifiable empty collection if the specified collection is {@code null}. * * @param the type of elements in the collection * @param c the collection for which an unmodifiable view is to be returned * @return an unmodifiable view of the specified collection, or an immutable/unmodifiable empty collection if the specified collection is null */ public static Collection unmodifiableCollection(final Collection c) { if (c == null) { return emptyList(); } return Collections.unmodifiableCollection(c); } /** * Returns an unmodifiable view of the specified list, or an immutable/unmodifiable empty list if the specified list is {@code null}. * * @param the type of elements in the list * @param list the list for which an unmodifiable view is to be returned * @return an unmodifiable view of the specified list, or an immutable/unmodifiable empty list if the specified list is null */ public static List unmodifiableList(final List list) { if (list == null) { return emptyList(); } return Collections.unmodifiableList(list); } /** * Returns an unmodifiable view of the specified set, or an immutable/unmodifiable empty set if the specified set is {@code null}. * * @param the type of elements in the set * @param s the set for which an unmodifiable view is to be returned * @return an unmodifiable view of the specified set, or an immutable/unmodifiable empty set if the specified set is null */ public static Set unmodifiableSet(final Set s) { if (s == null) { return emptySet(); } return Collections.unmodifiableSet(s); } /** * Returns an unmodifiable view of the specified sorted set, or an immutable/unmodifiable empty sorted set if the specified sorted set is {@code null}. * * @param the type of elements in the set * @param s the sorted set for which an unmodifiable view is to be returned * @return an unmodifiable view of the specified sorted set, or an immutable/unmodifiable empty sorted set if the specified sorted set is null */ public static SortedSet unmodifiableSortedSet(final SortedSet s) { if (s == null) { return emptySortedSet(); } return Collections.unmodifiableSortedSet(s); } /** * Returns an unmodifiable view of the specified navigable set, or an immutable/unmodifiable empty navigable set if the specified navigable set is {@code null}. * * @param the type of elements in the set * @param s the navigable set for which an unmodifiable view is to be returned * @return an unmodifiable view of the specified navigable set, or an immutable/unmodifiable empty navigable set if the specified navigable set is null */ public static NavigableSet unmodifiableNavigableSet(final NavigableSet s) { if (s == null) { return emptyNavigableSet(); } return Collections.unmodifiableNavigableSet(s); } /** * Returns an unmodifiable view of the specified map, or an immutable/unmodifiable empty map if the specified map is {@code null}. * * @param the type of keys in the map * @param the type of values in the map * @param m the map for which an unmodifiable view is to be returned * @return an unmodifiable view of the specified map, or an immutable/unmodifiable empty map if the specified map is null */ public static Map unmodifiableMap(final Map m) { if (m == null) { return emptyMap(); } return Collections.unmodifiableMap(m); } /** * Returns an unmodifiable view of the specified sorted map, or an immutable/unmodifiable empty sorted map if the specified map is {@code null}. * * @param the type of keys in the map * @param the type of values in the map * @param m the sorted map for which an unmodifiable view is to be returned * @return an unmodifiable view of the specified sorted map, or an immutable/unmodifiable empty sorted map if the specified map is null */ public static SortedMap unmodifiableSortedMap(final SortedMap m) { if (m == null) { return emptySortedMap(); } return Collections.unmodifiableSortedMap(m); } /** * Returns an unmodifiable view of the specified navigable map, or an immutable/unmodifiable empty navigable map if the specified map is {@code null}. * * @param the type of keys in the map * @param the type of values in the map * @param m the navigable map for which an unmodifiable view is to be returned * @return an unmodifiable view of the specified navigable map, or an immutable/unmodifiable empty navigable map if the specified map is null */ public static NavigableMap unmodifiableNavigableMap(final NavigableMap m) { if (m == null) { return emptyNavigableMap(); } return Collections.unmodifiableNavigableMap(m); } static Iterator getDescendingIteratorIfPossible(final Iterable c) { if (c instanceof Deque) { return ((Deque) c).descendingIterator(); } else { try { Method m = null; if ((m = ClassUtil.getDeclaredMethod(c.getClass(), "descendingIterator")) != null && Modifier.isPublic(m.getModifiers()) && Iterator.class.isAssignableFrom(m.getReturnType())) { return ClassUtil.invokeMethod(c, m); } } catch (final Exception e) { // continue } } return null; // NOSONAR } static int calculateBufferSize(final int len, final int elementPlusDelimiterLen) { return len > Integer.MAX_VALUE / elementPlusDelimiterLen ? Integer.MAX_VALUE : len * elementPlusDelimiterLen; } /** * Creates the mask. * * @param * @param interfaceClass * @return */ static T createMask(final Class interfaceClass) { final InvocationHandler h = (proxy, method, args) -> { throw new UnsupportedOperationException("It's a mask"); }; return newProxyInstance(interfaceClass, h); } }