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

com.landawn.abacus.util.Iterables 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) 2018, 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.math.BigDecimal;
import java.math.BigInteger;
import java.util.AbstractCollection;
import java.util.AbstractList;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.NavigableSet;
import java.util.NoSuchElementException;
import java.util.RandomAccess;
import java.util.Set;
import java.util.TreeSet;
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.SuppressFBWarnings;
import com.landawn.abacus.util.Range.BoundType;
import com.landawn.abacus.util.u.Nullable;
import com.landawn.abacus.util.u.Optional;
import com.landawn.abacus.util.u.OptionalByte;
import com.landawn.abacus.util.u.OptionalChar;
import com.landawn.abacus.util.u.OptionalDouble;
import com.landawn.abacus.util.u.OptionalFloat;
import com.landawn.abacus.util.u.OptionalInt;
import com.landawn.abacus.util.u.OptionalLong;
import com.landawn.abacus.util.u.OptionalShort;

/**
 * 

* 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. *

* * *

* 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 an 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. * *
* The methods in this class should only read the input {@code Collection/Array/Iterator} parameters, not modify them. * *
* The input parameters of most methods in this class should be {@code Iterable/Array}, instead of {@code Collection/Array}. * The returned type of most methods in this class should be a type of {@code Optional}, instead of element type of the input {@code Collection/Array}. * This class is a utility class, which is designed to extend the methods in {@code CommonUtil/N} class for handling empty input {@code Collection/Array/Iterator/Iterable} parameters or result. *

* * @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.N * @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 */ public final class Iterables { private Iterables() { // Utility class. } /** * Returns the minimum value from the provided array of characters. * If the array is {@code null} or empty, it returns an empty {@code OptionalChar}. * * @param a the array of characters to evaluate * @return an {@code OptionalChar} containing the minimum value if the array is not {@code null} or empty, otherwise an empty {@code OptionalChar} * @see N#min(char...) */ public static OptionalChar min(final char... a) { return a == null || a.length == 0 ? OptionalChar.empty() : OptionalChar.of(N.min(a)); } /** * Returns the minimum value from the provided array of bytes. * If the array is {@code null} or empty, it returns an empty {@code OptionalByte}. * * @param a the array of bytes to evaluate * @return an {@code OptionalByte} containing the minimum value if the array is not {@code null} or empty, otherwise an empty {@code OptionalByte} * @see N#min(byte...) */ public static OptionalByte min(final byte... a) { return a == null || a.length == 0 ? OptionalByte.empty() : OptionalByte.of(N.min(a)); } /** * Returns the minimum value from the provided array of shorts. * If the array is {@code null} or empty, it returns an empty {@code OptionalShort}. * * @param a the array of shorts to evaluate * @return an {@code OptionalShort} containing the minimum value if the array is not {@code null} or empty, otherwise an empty {@code OptionalShort} * @see N#min(short...) */ public static OptionalShort min(final short... a) { return a == null || a.length == 0 ? OptionalShort.empty() : OptionalShort.of(N.min(a)); } /** * Returns the minimum value from the provided array of integers. * If the array is {@code null} or empty, it returns an empty {@code OptionalInt}. * * @param a the array of integers to evaluate * @return an {@code OptionalInt} containing the minimum value if the array is not {@code null} or empty, otherwise an empty {@code OptionalInt} * @see N#min(int...) */ public static OptionalInt min(final int... a) { return a == null || a.length == 0 ? OptionalInt.empty() : OptionalInt.of(N.min(a)); } /** * Returns the minimum value from the provided array of longs. * If the array is {@code null} or empty, it returns an empty {@code OptionalLong}. * * @param a the array of longs to evaluate * @return an {@code OptionalLong} containing the minimum value if the array is not {@code null} or empty, otherwise an empty {@code OptionalLong} * @see N#min(long...) */ public static OptionalLong min(final long... a) { return a == null || a.length == 0 ? OptionalLong.empty() : OptionalLong.of(N.min(a)); } /** * Returns the minimum value from the provided array of floats. * If the array is {@code null} or empty, it returns an empty {@code OptionalFloat}. * * @param a the array of floats to evaluate * @return an {@code OptionalFloat} containing the minimum value if the array is not {@code null} or empty, otherwise an empty {@code OptionalFloat} * @see N#min(float...) */ public static OptionalFloat min(final float... a) { return a == null || a.length == 0 ? OptionalFloat.empty() : OptionalFloat.of(N.min(a)); } /** * Returns the minimum value from the provided array of doubles. * If the array is {@code null} or empty, it returns an empty {@code OptionalDouble}. * * @param a the array of doubles to evaluate * @return an {@code OptionalDouble} containing the minimum value if the array is not {@code null} or empty, otherwise an empty {@code OptionalDouble} * @see N#min(double...) */ public static OptionalDouble min(final double... a) { return a == null || a.length == 0 ? OptionalDouble.empty() : OptionalDouble.of(N.min(a)); } /** * Returns the minimum value from the provided array of elements based on their natural ordering. * Null values are considered to be maximum value. * If the array is {@code null} or empty, it returns an empty {@code Nullable}. * * @param a the array of elements to evaluate * @return a {@code Nullable} containing the minimum value if the array is not {@code null} or empty, otherwise an empty {@code Nullable} * @see N#min(Comparable...) */ public static > Nullable min(final T[] a) { return N.isEmpty(a) ? Nullable.empty() : Nullable.of(N.min(a)); } /** * Returns the minimum value from the provided array of elements according to the provided comparator. * If the array is {@code null} or empty, it returns an empty {@code Nullable}. * * @param a the array of elements to evaluate * @param cmp the comparator to determine the order of the elements * @return a {@code Nullable} containing the minimum value if the array is not {@code null} or empty, otherwise an empty {@code Nullable} * @see N#min(Object[], Comparator) */ public static Nullable min(final T[] a, final Comparator cmp) { return N.isEmpty(a) ? Nullable.empty() : Nullable.of(N.min(a, cmp)); } /** * Returns the minimum value from the provided iterable of elements based on their natural ordering. * Null values are considered to be maximum value. * If the iterable is {@code null} or empty, it returns an empty {@code Nullable}. * * @param c the iterable of elements to evaluate * @return a {@code Nullable} containing the minimum value if the iterable is not {@code null} or empty, otherwise an empty {@code Nullable} * @see N#min(Iterable) */ public static > Nullable min(final Iterable c) { return min(c, N.NULL_MAX_COMPARATOR); } /** * Returns the minimum value from the provided iterable of elements according to the provided comparator. * If the iterable is {@code null} or empty, it returns an empty {@code Nullable}. * * @param c the iterable of elements to * @param cmp the comparator to determine the order of the elements * @return a {@code Nullable} containing the minimum value if the iterable is not {@code null} or empty, otherwise an empty {@code Nullable} * @see N#min(Iterable, Comparator) */ public static Nullable min(final Iterable c, final Comparator cmp) { return c == null ? Nullable.empty() : min(c.iterator(), cmp); } /** * Returns the minimum value from the provided iterator of elements based on their natural ordering. * Null values are considered to be maximum value. * If the iterator is {@code null} or empty, it returns an empty {@code Nullable}. * * @param iter the iterator of elements to evaluate * @return a {@code Nullable} containing the minimum value if the iterator is not {@code null} or empty, otherwise an empty {@code Nullable} * @see N#min(Iterator) */ public static > Nullable min(final Iterator iter) { return min(iter, N.NULL_MAX_COMPARATOR); } /** * Returns the minimum value from the provided iterator of elements according to the provided comparator. * If the iterator is {@code null} or empty, it returns an empty {@code Nullable}. * * @param iter the iterator of elements to evaluate * @param cmp the comparator to determine the order of the elements * @return a {@code Nullable} containing the minimum value if the iterator is not {@code null} or empty, otherwise an empty {@code Nullable} * @see N#min(Iterator, Comparator) */ @SuppressFBWarnings("NP_LOAD_OF_KNOWN_NULL_VALUE") public static Nullable min(final Iterator iter, Comparator cmp) { cmp = cmp == null ? (Comparator) N.NULL_MAX_COMPARATOR : cmp; final boolean isNullMinComparator = cmp == N.NULL_MIN_COMPARATOR; if (iter == null || !iter.hasNext()) { return Nullable.empty(); } T candidate = null; T next = null; do { next = iter.next(); if (isNullMinComparator && next == null) { // NOSONAR //noinspection ConstantValue return Nullable.of(next); } else if (cmp.compare(next, candidate) < 0) { candidate = next; } } while (iter.hasNext()); return Nullable.of(candidate); } /** * Returns the minimum value from the provided array of elements according to the key extracted by the {@code keyExtractor} function. * Null values are considered to be maximum value. * If the array is {@code null} or empty, it returns an empty {@code Nullable}. * * @param a the array of elements to evaluate * @param keyExtractor the function to transform the elements into a comparable type for comparison * @return a {@code Nullable} containing the minimum value if the array is not {@code null} or empty, otherwise an empty {@code Nullable} * @see N#min(Object[], Comparator) */ @SuppressWarnings("rawtypes") public static Nullable minBy(final T[] a, final Function keyExtractor) { return min(a, Comparators.nullsLastBy(keyExtractor)); } /** * Returns the minimum value from the provided array of elements according to the key extracted by the {@code keyExtractor} function. * Null values are considered to be maximum value. * If the iterable is {@code null} or empty, it returns an empty {@code Nullable}. * * @param c the iterable of elements to evaluate * @param keyExtractor the function to transform the elements into a comparable type for comparison * @return a {@code Nullable} containing the minimum value if the iterable is not {@code null} or empty, otherwise an empty {@code Nullable} * @see N#min(Iterable, Comparator) */ @SuppressWarnings("rawtypes") public static Nullable minBy(final Iterable c, final Function keyExtractor) { return min(c, Comparators.nullsLastBy(keyExtractor)); } /** * Returns the minimum value from the provided array of elements according to the key extracted by the {@code keyExtractor} function. * Null values are considered to be maximum value. * If the iterator is {@code null} or empty, it returns an empty {@code Nullable}. * * @param iter the iterator of elements to evaluate * @param keyExtractor the function to transform the elements into a comparable type for comparison * @return a {@code Nullable} containing the minimum value if the iterator is not {@code null} or empty, otherwise an empty {@code Nullable} * @see N#min(Iterator, Comparator) */ @SuppressWarnings("rawtypes") public static Nullable minBy(final Iterator iter, final Function keyExtractor) { return min(iter, Comparators.nullsLastBy(keyExtractor)); } /** * Returns the minimum integer value extracted from the elements in the provided array by the input {@code valueExtractor} function. * If the array is {@code null} or empty, it returns an empty {@code OptionalInt}. * * @param the type of the elements in the array * @param a the array of elements to evaluate * @param valueExtractor the function to extract an integer value from each element * @return an {@code OptionalInt} containing the minimum value if the array is not {@code null} or empty, otherwise an empty {@code OptionalInt} * @see N#minIntOrDefaultIfEmpty(Object[], ToIntFunction, int) */ @Beta public static OptionalInt minInt(final T[] a, final ToIntFunction valueExtractor) { if (N.isEmpty(a)) { return OptionalInt.empty(); } int candidate = valueExtractor.applyAsInt(a[0]); int next = 0; for (int i = 1, len = a.length; i < len; i++) { next = valueExtractor.applyAsInt(a[i]); if (next < candidate) { candidate = next; } } return OptionalInt.of(candidate); } /** * Returns the minimum integer value extracted from the elements in the provided iterable by the input {@code valueExtractor} function. * If the iterable is {@code null} or empty, it returns an empty {@code OptionalInt}. * * @param the type of the elements in the iterable * @param c the iterable of elements to evaluate * @param valueExtractor the function to extract an integer value from each element * @return an {@code OptionalInt} containing the minimum value if the iterable is not {@code null} or empty, otherwise an empty {@code OptionalInt} * @see N#minIntOrDefaultIfEmpty(Iterable, ToIntFunction, int) */ @Beta public static OptionalInt minInt(final Iterable c, final ToIntFunction valueExtractor) { if (c == null) { return OptionalInt.empty(); } return minInt(c.iterator(), valueExtractor); } /** * Returns the minimum integer value extracted from the elements in the provided iterator by the input {@code valueExtractor} function. * If the iterator is {@code null} or empty, it returns an empty {@code OptionalInt}. * * @param the type of the elements in the iterator * @param iter the iterator of elements to evaluate * @param valueExtractor the function to extract an integer value from each element * @return an {@code OptionalInt} containing the minimum value if the iterator is not {@code null} or empty, otherwise an empty {@code OptionalInt} * @see N#minIntOrDefaultIfEmpty(Iterator, ToIntFunction, int) */ @Beta public static OptionalInt minInt(final Iterator iter, final ToIntFunction valueExtractor) { if (iter == null || !iter.hasNext()) { return OptionalInt.empty(); } int candidate = valueExtractor.applyAsInt(iter.next()); int next = 0; while (iter.hasNext()) { next = valueExtractor.applyAsInt(iter.next()); if (next < candidate) { candidate = next; } } return OptionalInt.of(candidate); } /** * Returns the minimum long value extracted from the elements in the provided array by the input {@code valueExtractor} function. * If the array is {@code null} or empty, it returns an empty {@code OptionalLong}. * * @param the type of the elements in the array * @param a the array of elements to evaluate * @param valueExtractor the function to extract a long value from each element * @return an {@code OptionalLong} containing the minimum value if the array is not {@code null} or empty, otherwise an empty {@code OptionalLong} * @see N#minLongOrDefaultIfEmpty(Object[], ToLongFunction, long) */ @Beta public static OptionalLong minLong(final T[] a, final ToLongFunction valueExtractor) { if (N.isEmpty(a)) { return OptionalLong.empty(); } long candidate = valueExtractor.applyAsLong(a[0]); long next = 0; for (int i = 1, len = a.length; i < len; i++) { next = valueExtractor.applyAsLong(a[i]); if (next < candidate) { candidate = next; } } return OptionalLong.of(candidate); } /** * Returns the minimum long value extracted from the elements in the provided iterable by the input {@code valueExtractor} function. * If the iterable is {@code null} or empty, it returns an empty {@code OptionalLong}. * * @param the type of the elements in the iterable * @param c the iterable of elements to evaluate * @param valueExtractor the function to extract a long value from each element * @return an {@code OptionalLong} containing the minimum value if the iterable is not {@code null} or empty, otherwise an empty {@code OptionalLong} * @see N#minLongOrDefaultIfEmpty(Iterable, ToLongFunction, long) */ @Beta public static OptionalLong minLong(final Iterable c, final ToLongFunction valueExtractor) { if (c == null) { return OptionalLong.empty(); } return minLong(c.iterator(), valueExtractor); } /** * Returns the minimum long value extracted from the elements in the provided iterator by the input {@code valueExtractor} function. * If the iterator is {@code null} or empty, it returns an empty {@code OptionalLong}. * * @param the type of the elements in the iterator * @param iter the iterator of elements to evaluate * @param valueExtractor the function to extract a long value from each element * @return an {@code OptionalLong} containing the minimum value if the iterator is not {@code null} or empty, otherwise an empty {@code OptionalLong} * @see N#minLongOrDefaultIfEmpty(Iterator, ToLongFunction, long) */ @Beta public static OptionalLong minLong(final Iterator iter, final ToLongFunction valueExtractor) { if (iter == null || !iter.hasNext()) { return OptionalLong.empty(); } long candidate = valueExtractor.applyAsLong(iter.next()); long next = 0; while (iter.hasNext()) { next = valueExtractor.applyAsLong(iter.next()); if (next < candidate) { candidate = next; } } return OptionalLong.of(candidate); } /** * Returns the minimum double value extracted from the elements in the provided array by the input {@code valueExtractor} function. * If the array is {@code null} or empty, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the array * @param a the array of elements to evaluate * @param valueExtractor the function to extract a double value from each element * @return an {@code OptionalDouble} containing the minimum value if the array is not {@code null} or empty, otherwise an empty {@code OptionalDouble} * @see N#minDoubleOrDefaultIfEmpty(Object[], ToDoubleFunction, double) */ @Beta public static OptionalDouble minDouble(final T[] a, final ToDoubleFunction valueExtractor) { if (N.isEmpty(a)) { return OptionalDouble.empty(); } double candidate = valueExtractor.applyAsDouble(a[0]); double next = 0; for (int i = 1, len = a.length; i < len; i++) { next = valueExtractor.applyAsDouble(a[i]); if (N.compare(next, candidate) < 0) { candidate = next; } } return OptionalDouble.of(candidate); } /** * Returns the minimum double value extracted from the elements in the provided iterable by the input {@code valueExtractor} function. * If the iterable is {@code null} or empty, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the iterable * @param c the iterable of elements to evaluate * @param valueExtractor the function to extract a double value from each element * @return an {@code OptionalDouble} containing the minimum value if the iterable is not {@code null} or empty, otherwise an empty {@code OptionalDouble} * @see N#minDoubleOrDefaultIfEmpty(Iterable, ToDoubleFunction, double) */ @Beta public static OptionalDouble minDouble(final Iterable c, final ToDoubleFunction valueExtractor) { if (c == null) { return OptionalDouble.empty(); } return minDouble(c.iterator(), valueExtractor); } /** * Returns the minimum double value extracted from the elements in the provided iterator by the input {@code valueExtractor} function. * If the iterator is {@code null} or empty, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the iterator * @param iter the iterator of elements to evaluate * @param valueExtractor the function to extract a double value from each element * @return an {@code OptionalDouble} containing the minimum value if the iterator is not {@code null} or empty, otherwise an empty {@code OptionalDouble} * @see N#minDoubleOrDefaultIfEmpty(Iterator, ToDoubleFunction, double) */ @Beta public static OptionalDouble minDouble(final Iterator iter, final ToDoubleFunction valueExtractor) { if (iter == null || !iter.hasNext()) { return OptionalDouble.empty(); } double candidate = valueExtractor.applyAsDouble(iter.next()); double next = 0; while (iter.hasNext()) { next = valueExtractor.applyAsDouble(iter.next()); if (N.compare(next, candidate) < 0) { candidate = next; } } return OptionalDouble.of(candidate); } /** * Returns the maximum value from the provided array of characters. * If the array is {@code null} or empty, it returns an empty {@code OptionalChar}. * * @param a the array of characters to evaluate * @return an {@code OptionalChar} containing the maximum value if the array is not {@code null} or empty, otherwise an empty {@code OptionalChar} * @see N#max(char...) */ public static OptionalChar max(final char... a) { return a == null || a.length == 0 ? OptionalChar.empty() : OptionalChar.of(N.max(a)); } /** * Returns the maximum value from the provided array of bytes. * If the array is {@code null} or empty, it returns an empty {@code OptionalByte}. * * @param a the array of bytes to evaluate * @return an {@code OptionalByte} containing the maximum value if the array is not {@code null} or empty, otherwise an empty {@code OptionalByte} * @see N#max(byte...) */ public static OptionalByte max(final byte... a) { return a == null || a.length == 0 ? OptionalByte.empty() : OptionalByte.of(N.max(a)); } /** * Returns the maximum value from the provided array of shorts. * If the array is {@code null} or empty, it returns an empty {@code OptionalShort}. * * @param a the array of shorts to evaluate * @return an {@code OptionalShort} containing the maximum value if the array is not {@code null} or empty, otherwise an empty {@code OptionalShort} * @see N#max(short...) */ public static OptionalShort max(final short... a) { return a == null || a.length == 0 ? OptionalShort.empty() : OptionalShort.of(N.max(a)); } /** * Returns the maximum value from the provided array of integers. * If the array is {@code null} or empty, it returns an empty {@code OptionalInt}. * * @param a the array of integers to evaluate * @return an {@code OptionalInt} containing the maximum value if the array is not {@code null} or empty, otherwise an empty {@code OptionalInt} * @see N#max(int...) */ public static OptionalInt max(final int... a) { return a == null || a.length == 0 ? OptionalInt.empty() : OptionalInt.of(N.max(a)); } /** * Returns the maximum value from the provided array of longs. * If the array is {@code null} or empty, it returns an empty {@code OptionalLong}. * * @param a the array of longs to evaluate * @return an {@code OptionalLong} containing the maximum value if the array is not {@code null} or empty, otherwise an empty {@code OptionalLong} * @see N#max(long...) */ public static OptionalLong max(final long... a) { return a == null || a.length == 0 ? OptionalLong.empty() : OptionalLong.of(N.max(a)); } /** * Returns the maximum value from the provided array of floats. * If the array is {@code null} or empty, it returns an empty {@code OptionalFloat}. * * @param a the array of floats to evaluate * @return an {@code OptionalFloat} containing the maximum value if the array is not {@code null} or empty, otherwise an empty {@code OptionalFloat} * @see N#max(float...) */ public static OptionalFloat max(final float... a) { return a == null || a.length == 0 ? OptionalFloat.empty() : OptionalFloat.of(N.max(a)); } /** * Returns the maximum value from the provided array of doubles. * If the array is {@code null} or empty, it returns an empty {@code OptionalDouble}. * * @param a the array of doubles to evaluate * @return an {@code OptionalDouble} containing the maximum value if the array is not {@code null} or empty, otherwise an empty {@code OptionalDouble} * @see N#max(double...) */ public static OptionalDouble max(final double... a) { return a == null || a.length == 0 ? OptionalDouble.empty() : OptionalDouble.of(N.max(a)); } /** * Returns the maximum value from the provided array of elements based on their natural ordering. * Null values are considered to be minimum * If the array is {@code null} or empty, it returns an empty {@code Nullable}. * * @param a the array of elements to evaluate * @return a {@code Nullable} containing the maximum value if the array is not {@code null} or empty, otherwise an empty {@code Nullable} * @see N#max(Comparable...) */ public static > Nullable max(final T[] a) { return N.isEmpty(a) ? Nullable.empty() : Nullable.of(N.max(a)); } /** * Returns the maximum value from the provided array of elements according to the provided comparator. * If the array is {@code null} or empty, it returns an empty {@code Nullable}. * * @param a the array of elements to evaluate * @param cmp the comparator to determine the order of the elements * @return a {@code Nullable} containing the maximum value if the array is not {@code null} or empty, otherwise an empty {@code Nullable} * @see N#max(Object[], Comparator) */ public static Nullable max(final T[] a, final Comparator cmp) { return N.isEmpty(a) ? Nullable.empty() : Nullable.of(N.max(a, cmp)); } /** * Returns the maximum value from the provided iterable of elements based on their natural ordering. * Null values are considered to be minimum * If the iterable is {@code null} or empty, it returns an empty {@code Nullable}. * * @param c the iterable of elements to evaluate * @return a {@code Nullable} containing the maximum value if the iterable is not {@code null} or empty, otherwise an empty {@code Nullable} * @see N#max(Iterable) */ public static > Nullable max(final Iterable c) { return max(c, N.NULL_MIN_COMPARATOR); } /** * Returns the maximum value from the provided iterable of elements according to the provided comparator. * If the iterable is {@code null} or empty, it returns an empty {@code Nullable}. * * @param c the iterable of elements to * @param cmp the comparator to determine the order of the elements * @return a {@code Nullable} containing the maximum value if the iterable is not {@code null} or empty, otherwise an empty {@code Nullable} * @see N#max(Iterable, Comparator) */ public static Nullable max(final Iterable c, final Comparator cmp) { return c == null ? Nullable.empty() : max(c.iterator(), cmp); } /** * Returns the maximum value from the provided iterator of elements based on their natural ordering. * Null values are considered to be minimum * If the iterator is {@code null} or empty, it returns an empty {@code Nullable}. * * @param iter the iterator of elements to evaluate * @return a {@code Nullable} containing the maximum value if the iterator is not {@code null} or empty, otherwise an empty {@code Nullable} * @see N#max(Iterator) */ public static > Nullable max(final Iterator iter) { return max(iter, N.NULL_MIN_COMPARATOR); } /** * Returns the maximum value from the provided iterator of elements according to the provided comparator. * If the iterator is {@code null} or empty, it returns an empty {@code Nullable}. * * @param iter the iterator of elements to evaluate * @param cmp the comparator to determine the order of the elements * @return a {@code Nullable} containing the maximum value if the iterator is not {@code null} or empty, otherwise an empty {@code Nullable} * @see N#max(Iterator, Comparator) */ @SuppressFBWarnings("NP_LOAD_OF_KNOWN_NULL_VALUE") public static Nullable max(final Iterator iter, Comparator cmp) { cmp = cmp == null ? (Comparator) N.NULL_MIN_COMPARATOR : cmp; final boolean isNullMaxComparator = cmp == N.NULL_MAX_COMPARATOR; if (iter == null || !iter.hasNext()) { return Nullable.empty(); } T candidate = null; T next = null; do { next = iter.next(); if (isNullMaxComparator && next == null) { // NOSONAR //noinspection ConstantValue return Nullable.of(next); } else if (cmp.compare(next, candidate) > 0) { candidate = next; } } while (iter.hasNext()); return Nullable.of(candidate); } /** * Returns the maximum value from the provided array of elements according to the key extracted by the {@code keyExtractor} function. * Null values are considered to be minimum * If the array is {@code null} or empty, it returns an empty {@code Nullable}. * * @param a the array of elements to evaluate * @param keyExtractor the function to transform the elements into a comparable type for comparison * @return a {@code Nullable} containing the maximum value if the array is not {@code null} or empty, otherwise an empty {@code Nullable} * @see N#max(Object[], Comparator) */ @SuppressWarnings("rawtypes") public static Nullable maxBy(final T[] a, final Function keyExtractor) { return max(a, Comparators.nullsFirstBy(keyExtractor)); } /** * Returns the maximum value from the provided array of elements according to the key extracted by the {@code keyExtractor} function. * Null values are considered to be minimum * If the iterable is {@code null} or empty, it returns an empty {@code Nullable}. * * @param c the iterable of elements to evaluate * @param keyExtractor the function to transform the elements into a comparable type for comparison * @return a {@code Nullable} containing the maximum value if the iterable is not {@code null} or empty, otherwise an empty {@code Nullable} * @see N#max(Iterable, Comparator) */ @SuppressWarnings("rawtypes") public static Nullable maxBy(final Iterable c, final Function keyExtractor) { return max(c, Comparators.nullsFirstBy(keyExtractor)); } /** * Returns the maximum value from the provided array of elements according to the key extracted by the {@code keyExtractor} function. * Null values are considered to be minimum * If the iterator is {@code null} or empty, it returns an empty {@code Nullable}. * * @param iter the iterator of elements to evaluate * @param keyExtractor the function to transform the elements into a comparable type for comparison * @return a {@code Nullable} containing the maximum value if the iterator is not {@code null} or empty, otherwise an empty {@code Nullable} * @see N#max(Iterator, Comparator) */ @SuppressWarnings("rawtypes") public static Nullable maxBy(final Iterator iter, final Function keyExtractor) { return max(iter, Comparators.nullsFirstBy(keyExtractor)); } /** * Returns the maximum integer value extracted from the elements in the provided array by the input {@code valueExtractor} function. * If the array is {@code null} or empty, it returns an empty {@code OptionalInt}. * * @param the type of the elements in the array * @param a the array of elements to evaluate * @param valueExtractor the function to extract an integer value from each element * @return an {@code OptionalInt} containing the maximum value if the array is not {@code null} or empty, otherwise an empty {@code OptionalInt} * @see N#maxIntOrDefaultIfEmpty(Object[], ToIntFunction, int) */ @Beta public static OptionalInt maxInt(final T[] a, final ToIntFunction valueExtractor) { if (N.isEmpty(a)) { return OptionalInt.empty(); } int candidate = valueExtractor.applyAsInt(a[0]); int next = 0; for (int i = 1, len = a.length; i < len; i++) { next = valueExtractor.applyAsInt(a[i]); if (next > candidate) { candidate = next; } } return OptionalInt.of(candidate); } /** * Returns the maximum integer value extracted from the elements in the provided iterable by the input {@code valueExtractor} function. * If the iterable is {@code null} or empty, it returns an empty {@code OptionalInt}. * * @param the type of the elements in the iterable * @param c the iterable of elements to evaluate * @param valueExtractor the function to extract an integer value from each element * @return an {@code OptionalInt} containing the maximum value if the iterable is not {@code null} or empty, otherwise an empty {@code OptionalInt} * @see N#maxIntOrDefaultIfEmpty(Iterable, ToIntFunction, int) */ @Beta public static OptionalInt maxInt(final Iterable c, final ToIntFunction valueExtractor) { if (c == null) { return OptionalInt.empty(); } return maxInt(c.iterator(), valueExtractor); } /** * Returns the maximum integer value extracted from the elements in the provided iterator by the input {@code valueExtractor} function. * If the iterator is {@code null} or empty, it returns an empty {@code OptionalInt}. * * @param the type of the elements in the iterator * @param iter the iterator of elements to evaluate * @param valueExtractor the function to extract an integer value from each element * @return an {@code OptionalInt} containing the maximum value if the iterator is not {@code null} or empty, otherwise an empty {@code OptionalInt} * @see N#maxIntOrDefaultIfEmpty(Iterator, ToIntFunction, int) */ @Beta public static OptionalInt maxInt(final Iterator iter, final ToIntFunction valueExtractor) { if (iter == null || !iter.hasNext()) { return OptionalInt.empty(); } int candidate = valueExtractor.applyAsInt(iter.next()); int next = 0; while (iter.hasNext()) { next = valueExtractor.applyAsInt(iter.next()); if (next > candidate) { candidate = next; } } return OptionalInt.of(candidate); } /** * Returns the maximum long value extracted from the elements in the provided array by the input {@code valueExtractor} function. * If the array is {@code null} or empty, it returns an empty {@code OptionalLong}. * * @param the type of the elements in the array * @param a the array of elements to evaluate * @param valueExtractor the function to extract a long value from each element * @return an {@code OptionalLong} containing the maximum value if the array is not {@code null} or empty, otherwise an empty {@code OptionalLong} * @see N#maxLongOrDefaultIfEmpty(Object[], ToLongFunction, long) */ @Beta public static OptionalLong maxLong(final T[] a, final ToLongFunction valueExtractor) { if (N.isEmpty(a)) { return OptionalLong.empty(); } long candidate = valueExtractor.applyAsLong(a[0]); long next = 0; for (int i = 1, len = a.length; i < len; i++) { next = valueExtractor.applyAsLong(a[i]); if (next > candidate) { candidate = next; } } return OptionalLong.of(candidate); } /** * Returns the maximum long value extracted from the elements in the provided iterable by the input {@code valueExtractor} function. * If the iterable is {@code null} or empty, it returns an empty {@code OptionalLong}. * * @param the type of the elements in the iterable * @param c the iterable of elements to evaluate * @param valueExtractor the function to extract a long value from each element * @return an {@code OptionalLong} containing the maximum value if the iterable is not {@code null} or empty, otherwise an empty {@code OptionalLong} * @see N#maxLongOrDefaultIfEmpty(Iterable, ToLongFunction, long) */ @Beta public static OptionalLong maxLong(final Iterable c, final ToLongFunction valueExtractor) { if (c == null) { return OptionalLong.empty(); } return maxLong(c.iterator(), valueExtractor); } /** * Returns the maximum long value extracted from the elements in the provided iterator by the input {@code valueExtractor} function. * If the iterator is {@code null} or empty, it returns an empty {@code OptionalLong}. * * @param the type of the elements in the iterator * @param iter the iterator of elements to evaluate * @param valueExtractor the function to extract a long value from each element * @return an {@code OptionalLong} containing the maximum value if the iterator is not {@code null} or empty, otherwise an empty {@code OptionalLong} * @see N#maxLongOrDefaultIfEmpty(Iterator, ToLongFunction, long) */ @Beta public static OptionalLong maxLong(final Iterator iter, final ToLongFunction valueExtractor) { if (iter == null || !iter.hasNext()) { return OptionalLong.empty(); } long candidate = valueExtractor.applyAsLong(iter.next()); long next = 0; while (iter.hasNext()) { next = valueExtractor.applyAsLong(iter.next()); if (next > candidate) { candidate = next; } } return OptionalLong.of(candidate); } /** * Returns the maximum double value extracted from the elements in the provided array by the input {@code valueExtractor} function. * If the array is {@code null} or empty, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the array * @param a the array of elements to evaluate * @param valueExtractor the function to extract a double value from each element * @return an {@code OptionalDouble} containing the maximum value if the array is not {@code null} or empty, otherwise an empty {@code OptionalDouble} * @see N#maxDoubleOrDefaultIfEmpty(Object[], ToDoubleFunction, double) */ @Beta public static OptionalDouble maxDouble(final T[] a, final ToDoubleFunction valueExtractor) { if (N.isEmpty(a)) { return OptionalDouble.empty(); } double candidate = valueExtractor.applyAsDouble(a[0]); double next = 0; for (int i = 1, len = a.length; i < len; i++) { next = valueExtractor.applyAsDouble(a[i]); if (N.compare(next, candidate) > 0) { candidate = next; } } return OptionalDouble.of(candidate); } /** * Returns the maximum double value extracted from the elements in the provided iterable by the input {@code valueExtractor} function. * If the iterable is {@code null} or empty, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the iterable * @param c the iterable of elements to evaluate * @param valueExtractor the function to extract a double value from each element * @return an {@code OptionalDouble} containing the maximum value if the iterable is not {@code null} or empty, otherwise an empty {@code OptionalDouble} * @see N#maxDoubleOrDefaultIfEmpty(Iterable, ToDoubleFunction, double) */ @Beta public static OptionalDouble maxDouble(final Iterable c, final ToDoubleFunction valueExtractor) { if (c == null) { return OptionalDouble.empty(); } return maxDouble(c.iterator(), valueExtractor); } /** * Returns the maximum double value extracted from the elements in the provided iterator by the input {@code valueExtractor} function. * If the iterator is {@code null} or empty, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the iterator * @param iter the iterator of elements to evaluate * @param valueExtractor the function to extract a double value from each element * @return an {@code OptionalDouble} containing the maximum value if the iterator is not {@code null} or empty, otherwise an empty {@code OptionalDouble} * @see N#maxDoubleOrDefaultIfEmpty(Iterator, ToDoubleFunction, double) */ @Beta public static OptionalDouble maxDouble(final Iterator iter, final ToDoubleFunction valueExtractor) { if (iter == null || !iter.hasNext()) { return OptionalDouble.empty(); } double candidate = valueExtractor.applyAsDouble(iter.next()); double next = 0; while (iter.hasNext()) { next = valueExtractor.applyAsDouble(iter.next()); if (N.compare(next, candidate) > 0) { candidate = next; } } return OptionalDouble.of(candidate); } /** * Returns the minimum and maximum values from the provided array of elements based on their natural ordering. * The result is wrapped in an Optional Pair, where the first element is the minimum and the second is the maximum. * If the array is {@code null} or empty, it returns an empty Optional. * * @param a the array of elements to evaluate * @return an Optional Pair containing the minimum and maximum values if the array is not {@code null} or empty, otherwise an empty Optional * @see N#minMax(Comparable...) */ public static > Optional> minMax(final T[] a) { return N.isEmpty(a) ? Optional.empty() : Optional.of(N.minMax(a)); } /** * Returns the minimum and maximum values from the provided array of elements according to the provided comparator. * The result is wrapped in an Optional Pair, where the first element is the minimum and the second is the maximum. * If the array is {@code null} or empty, it returns an empty Optional. * * @param the type of the elements in the array * @param a the array of elements to evaluate * @param cmp the comparator to determine the order of the elements * @return an Optional Pair containing the minimum and maximum values if the array is not {@code null} or empty, otherwise an empty Optional * @see N#minMax(Object[], Comparator) */ public static Optional> minMax(final T[] a, final Comparator cmp) { return N.isEmpty(a) ? Optional.empty() : Optional.of(N.minMax(a, cmp)); } /** * Returns the minimum and maximum values from the provided iterable of elements based on their natural ordering. * The result is wrapped in an Optional Pair, where the first element is the minimum and the second is the maximum. * If the iterable is {@code null} or empty, it returns an empty Optional. * * @param c the iterable of elements to evaluate * @return an Optional Pair containing the minimum and maximum values if the iterable is not {@code null} or empty, otherwise an empty Optional * @see N#minMax(Iterable) */ public static > Optional> minMax(final Iterable c) { final Iterator iter = c == null ? null : c.iterator(); return iter == null || !iter.hasNext() ? Optional.empty() : Optional.of(N.minMax(iter)); } /** * Returns the minimum and maximum values from the provided iterable of elements, according to the provided comparator. * The result is wrapped in an Optional Pair, where the first element is the minimum and the second is the maximum. * If the iterable is {@code null} or empty, it returns an empty Optional. * * @param c the iterable of elements to evaluate * @param cmp the comparator to determine the order of the elements * @return an Optional Pair containing the minimum and maximum values if the iterable is not {@code null} or empty, otherwise an empty Optional * @see N#minMax(Iterable, Comparator) */ public static Optional> minMax(final Iterable c, final Comparator cmp) { final Iterator iter = c == null ? null : c.iterator(); return iter == null || !iter.hasNext() ? Optional.empty() : Optional.of(N.minMax(iter, cmp)); } /** * Returns the minimum and maximum values from the provided iterator of elements based on their natural ordering. * The result is wrapped in an Optional Pair, where the first element is the minimum and the second is the maximum. * If the iterator is {@code null} or empty, it returns an empty Optional. * * @param iter the iterator of elements to evaluate * @return an Optional Pair containing the minimum and maximum values if the iterator is not {@code null} or empty, otherwise an empty Optional * @see N#minMax(Iterator) */ public static > Optional> minMax(final Iterator iter) { return iter == null || !iter.hasNext() ? Optional.empty() : Optional.of(N.minMax(iter)); } /** * Returns the minimum and maximum values from the provided iterator of elements, according to the provided comparator. * The result is wrapped in an Optional Pair, where the first element is the minimum and the second is the maximum. * If the iterator is {@code null} or empty, it returns an empty Optional. * * @param iter the iterator of elements to evaluate * @param cmp the comparator to determine the order of the elements * @return an Optional Pair containing the minimum and maximum values if the iterator is not {@code null} or empty, otherwise an empty Optional * @see N#minMax(Iterator, Comparator) */ public static Optional> minMax(final Iterator iter, final Comparator cmp) { return iter == null || !iter.hasNext() ? Optional.empty() : Optional.of(N.minMax(iter, cmp)); } /** * Returns the length / 2 + 1 largest value in the specified array based on their natural ordering. * The result is wrapped in a {@code Nullable}. If the array is {@code null} or empty, it returns an empty {@code Nullable}. * * @param the type of the elements in the array, which must be a subtype of Comparable * @param a the array of elements to evaluate * @return a {@code Nullable} containing the median value if the array is not {@code null} or empty, otherwise an empty {@code Nullable} * @see N#median(Comparable...) * @see Median#of(Comparable[]) * @see Median#of(Object[], Comparator) */ public static > Nullable median(final T[] a) { return N.isEmpty(a) ? Nullable.empty() : Nullable.of(N.median(a)); } /** * Returns the length / 2 + 1 largest value in the specified array, according to the provided comparator. * The result is wrapped in a {@code Nullable}. If the array is {@code null} or empty, it returns an empty {@code Nullable}. * * @param the type of the elements in the array, which must be a subtype of Comparable * @param a the array of elements to evaluate * @param cmp the comparator to determine the order of the elements * @return a {@code Nullable} containing the median value if the array is not {@code null} or empty, otherwise an empty {@code Nullable} * @see N#median(Object[], Comparator) * @see Median#of(Comparable[]) * @see Median#of(Object[], Comparator) */ public static Nullable median(final T[] a, final Comparator cmp) { return N.isEmpty(a) ? Nullable.empty() : Nullable.of(N.median(a, cmp)); } /** * Returns the length / 2 + 1 largest value in the specified collection based on their natural ordering. * The result is wrapped in a {@code Nullable}. If the collection is {@code null} or empty, it returns an empty {@code Nullable}. * * @param the type of the elements in the collection, which must be a subtype of Comparable * @param c the collection of elements to evaluate * @return a {@code Nullable} containing the median value if the collection is not {@code null} or empty, otherwise an empty {@code Nullable} * @see N#median(Collection) * @see Median#of(Collection) * @see Median#of(Collection, Comparator) */ public static > Nullable median(final Collection c) { return N.isEmpty(c) ? Nullable.empty() : Nullable.of(N.median(c)); } /** * Returns the length / 2 + 1 largest value in the specified collection, according to the provided comparator. * The result is wrapped in a {@code Nullable}. If the collection is {@code null} or empty, it returns an empty {@code Nullable}. * * @param the type of the elements in the collection, which must be a subtype of Comparable * @param c the collection of elements to evaluate * @param cmp the comparator to determine the order of the elements * @return a {@code Nullable} containing the median value if the collection is not {@code null} or empty, otherwise an empty {@code Nullable} * @see N#median(Collection, Comparator) * @see Median#of(Collection) * @see Median#of(Collection, Comparator) */ public static Nullable median(final Collection c, final Comparator cmp) { return N.isEmpty(c) ? Nullable.empty() : Nullable.of(N.median(c, cmp)); } // /** // * Returns {@code Nullable.empty()} if the specified {@code Array/Collection} is {@code null} or empty. // * // * @param // * @param a // * @param keyExtractor // * @return // * @deprecated // * @see Comparators#comparingBy(Function) // */ // @Deprecated // @Beta // @SuppressWarnings("rawtypes") // public static Nullable medianBy(final T[] a, final Function keyExtractor) { // return median(a, Comparators.comparingBy(keyExtractor)); // } // // /** // * Returns {@code Nullable.empty()} if the specified {@code Array/Collection} is {@code null} or empty. // * // * @param // * @param c // * @param keyExtractor // * @return // * @deprecated // * @see Comparators#comparingBy(Function) // */ // @Deprecated // @Beta // @SuppressWarnings("rawtypes") // public static Nullable medianBy(final Collection c, final Function keyExtractor) { // return median(c, Comparators.comparingBy(keyExtractor)); // } /** * Returns the k-th largest element from the provided array based on their natural ordering. * If the array is {@code null}, empty, or its length is less than {@code k}, it returns an empty {@code Nullable}. * * @param the type of the elements in the array, which must be a subtype of Comparable * @param a the array of elements to evaluate * @param k the position of the largest element to find (1-based index) * @return a {@code Nullable} containing the k-th largest value if the array is not {@code null}, not empty, and its length is greater or equal to {@code k}, otherwise an empty {@code Nullable} * @see N#kthLargest(Comparable[], int) */ public static > Nullable kthLargest(final T[] a, final int k) { return N.isEmpty(a) || a.length < k ? Nullable.empty() : Nullable.of(N.kthLargest(a, k)); } /** * Returns the k-th largest element from the provided array according to the provided comparator. * If the array is {@code null}, empty, or its length is less than {@code k}, it returns an empty {@code Nullable}. * * @param the type of the elements in the array * @param a the array of elements to evaluate * @param k the position of the largest element to find (1-based index) * @param cmp the comparator to determine the order of the elements * @return a {@code Nullable} containing the k-th largest value if the array is not {@code null}, not empty, and its length is greater or equal to {@code k}, otherwise an empty {@code Nullable} * @see N#kthLargest(Object[], int, Comparator) */ public static Nullable kthLargest(final T[] a, final int k, final Comparator cmp) { return N.isEmpty(a) || a.length < k ? Nullable.empty() : Nullable.of(N.kthLargest(a, k, cmp)); } /** * Returns the k-th largest element from the provided collection based on their natural ordering. * If the collection is {@code null}, empty, or its size is less than {@code k}, it returns an empty {@code Nullable}. * * @param the type of the elements in the collection, which must be a subtype of Comparable * @param c the collection of elements to evaluate * @param k the position of the largest element to find (1-based index) * @return a {@code Nullable} containing the k-th largest value if the collection is not {@code null}, not empty, and its size is greater or equal to {@code k}, otherwise an empty {@code Nullable} * @see N#kthLargest(Collection, int) */ public static > Nullable kthLargest(final Collection c, final int k) { return N.isEmpty(c) || c.size() < k ? Nullable.empty() : Nullable.of(N.kthLargest(c, k)); } /** * Returns the k-th largest element from the provided collection based on the provided comparator. * If the collection is {@code null}, empty, or its size is less than k, a {@code Nullable}.empty() is returned. * * @param The type of elements in the collection. * @param c The collection from which to find the k-th largest element. * @param k The position from the end of a sorted list of the collection's elements (1-based index). * @param cmp The comparator used to determine the order of the collection's elements. * @return A {@code Nullable} containing the k-th largest element if it exists, otherwise {@code Nullable}.empty(). * @see N#kthLargest(Collection, int, Comparator) */ public static Nullable kthLargest(final Collection c, final int k, final Comparator cmp) { return N.isEmpty(c) || c.size() < k ? Nullable.empty() : Nullable.of(N.kthLargest(c, k, cmp)); } /** * Returns the sum of the integer value of provided numbers as an {@code OptionalInt}. * If the iterable is {@code null} or empty, it returns an empty {@code OptionalInt}. * * @param the type of the elements in the iterable, which must be a subtype of Number * @param c the iterable of elements to evaluate * @return an {@code OptionalInt} containing the sum if the iterable is not {@code null} or empty, otherwise an empty {@code OptionalInt} * @see N#sumInt(Iterable) */ public static OptionalInt sumInt(final Iterable c) { return sumInt(c, Fn.numToInt()); } /** * Returns the sum of the integer values extracted from the elements in the provided iterable by the input {@code func} function. * If the iterable is {@code null} or empty, it returns an empty {@code OptionalInt}. * * @param the type of the elements in the iterable * @param c the iterable of elements to evaluate * @param func the function to extract an integer value from each element * @return an {@code OptionalInt} containing the sum if the iterable is not {@code null} or empty, otherwise an empty {@code OptionalInt} * @see N#sumInt(Iterable, ToIntFunction) */ public static OptionalInt sumInt(final Iterable c, final ToIntFunction func) { final Iterator iter = c == null ? ObjIterator.empty() : c.iterator(); if (!iter.hasNext()) { return OptionalInt.empty(); } return OptionalInt.of(N.sumInt(c, func)); } /** * Returns the sum of the integer values of the provided numbers as an {@code OptionalLong}. * If the iterable is {@code null} or empty, it returns an empty {@code OptionalLong}. * * @param the type of the elements in the iterable, which must be a subtype of Number * @param c the iterable of elements to evaluate * @return an {@code OptionalLong} containing the sum if the iterable is not {@code null} or empty, otherwise an empty {@code OptionalLong} * @see N#sumIntToLong(Iterable) */ public static OptionalLong sumIntToLong(final Iterable c) { return sumIntToLong(c, Fn.numToInt()); } /** * Returns the sum of the integer values extracted from the elements in the provided iterable by the input {@code func} function as an {@code OptionalLong}. * If the iterable is {@code null} or empty, it returns an empty {@code OptionalLong}. * * @param the type of the elements in the iterable * @param c the iterable of elements to evaluate * @param func the function to extract an integer value from each element * @return an {@code OptionalLong} containing the sum if the iterable is not {@code null} or empty, otherwise an empty {@code OptionalLong} * @see N#sumIntToLong(Iterable, ToIntFunction) */ public static OptionalLong sumIntToLong(final Iterable c, final ToIntFunction func) { final Iterator iter = c == null ? ObjIterator.empty() : c.iterator(); if (!iter.hasNext()) { return OptionalLong.empty(); } return OptionalLong.of(N.sumIntToLong(c, func)); } /** * Returns the sum of the long values of the provided numbers as an {@code OptionalLong}. * If the iterable is {@code null} or empty, it returns an empty {@code OptionalLong}. * * @param the type of the elements in the iterable, which must be a subtype of Number * @param c the iterable of elements to evaluate * @return an {@code OptionalLong} containing the sum if the iterable is not {@code null} or empty, otherwise an empty {@code OptionalLong} * @see N#sumLong(Iterable) */ public static OptionalLong sumLong(final Iterable c) { return sumLong(c, Fn.numToLong()); } /** * Returns the sum of the long values extracted from the elements in the provided iterable by the input {@code func} function. * If the iterable is {@code null} or empty, it returns an empty {@code OptionalLong}. * * @param the type of the elements in the iterable * @param c the iterable of elements to evaluate * @param func the function to extract a long value from each element * @return an {@code OptionalLong} containing the sum if the iterable is not {@code null} or empty, otherwise an empty {@code OptionalLong} * @see N#sumLong(Iterable, ToLongFunction) */ public static OptionalLong sumLong(final Iterable c, final ToLongFunction func) { final Iterator iter = c == null ? ObjIterator.empty() : c.iterator(); if (!iter.hasNext()) { return OptionalLong.empty(); } return OptionalLong.of(N.sumLong(c, func)); } /** * Returns the sum of the double values of the provided numbers as an {@code OptionalDouble}. * If the iterable is {@code null} or empty, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the iterable, which must be a subtype of Number * @param c the iterable of elements to evaluate * @return an {@code OptionalDouble} containing the sum if the iterable is not {@code null} or empty, otherwise an empty {@code OptionalDouble} * @see N#sumDouble(Iterable) */ public static OptionalDouble sumDouble(final Iterable c) { return sumDouble(c, Fn.numToDouble()); } /** * Returns the sum of the double values extracted from the elements in the provided iterable by the input {@code func} function. * If the iterable is {@code null} or empty, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the iterable * @param c the iterable of elements to evaluate * @param func the function to extract a double value from each element * @return an {@code OptionalDouble} containing the sum if the iterable is not {@code null} or empty, otherwise an empty {@code OptionalDouble} * @see N#sumDouble(Iterable, ToDoubleFunction) */ public static OptionalDouble sumDouble(final Iterable c, final ToDoubleFunction func) { final Iterator iter = c == null ? ObjIterator.empty() : c.iterator(); if (!iter.hasNext()) { return OptionalDouble.empty(); } return OptionalDouble.of(N.sumDouble(c, func)); } /** * Returns the sum of the BigInteger values in the provided iterable. * If the iterable is {@code null} or empty, it returns an empty {@code Optional}. * * @param c the iterable of BigInteger elements to evaluate * @return an {@code Optional} containing the sum if the iterable is not {@code null} or empty, otherwise an empty {@code Optional} * @see N#sumBigInteger(Iterable) */ public static Optional sumBigInteger(final Iterable c) { return sumBigInteger(c, Fn.identity()); } /** * Returns the sum of the BigInteger values extracted from the elements in the provided iterable by the input {@code func} function. * If the iterable is {@code null} or empty, it returns an empty {@code Optional}. * * @param the type of the elements in the iterable * @param c the iterable of elements to evaluate * @param func the function to extract a BigInteger value from each element * @return an {@code Optional} containing the sum if the iterable is not {@code null} or empty, otherwise an empty {@code Optional} * @see N#sumBigInteger(Iterable, Function) */ public static Optional sumBigInteger(final Iterable c, final Function func) { final Iterator iter = c == null ? ObjIterator.empty() : c.iterator(); if (!iter.hasNext()) { return Optional.empty(); } return Optional.of(N.sumBigInteger(c, func)); } /** * Returns the sum of the BigDecimal values in the provided iterable. * If the iterable is {@code null} or empty, it returns an empty {@code Optional}. * * @param c the iterable of BigDecimal elements to evaluate * @return an {@code Optional} containing the sum if the iterable is not {@code null} or empty, otherwise an empty {@code Optional} * @see N#sumBigDecimal(Iterable) */ public static Optional sumBigDecimal(final Iterable c) { return sumBigDecimal(c, Fn.identity()); } /** * Returns the sum of the BigDecimal values extracted from the elements in the provided iterable by the input {@code func} function. * If the iterable is {@code null} or empty, it returns an empty {@code Optional}. * * @param the type of the elements in the iterable * @param c the iterable of elements to evaluate * @param func the function to extract a BigDecimal value from each element * @return an {@code Optional} containing the sum if the iterable is not {@code null} or empty, otherwise an empty {@code Optional} * @see N#sumBigDecimal(Iterable, Function) */ public static Optional sumBigDecimal(final Iterable c, final Function func) { final Iterator iter = c == null ? ObjIterator.empty() : c.iterator(); if (!iter.hasNext()) { return Optional.empty(); } return Optional.of(N.sumBigDecimal(c, func)); } /** * Returns the average of the integer values of the provided numbers as an {@code OptionalDouble}. * If the array is {@code null} or empty, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the array, which must be a subtype of Number * @param a the array of elements to evaluate * @return the average of the integer values if the array is not {@code null} or empty, otherwise an empty {@code OptionalDouble} * @see N#averageInt(Number[]) */ public static OptionalDouble averageInt(final T[] a) { return averageInt(a, Fn.numToInt()); } /** * Returns the average of the integer values of the provided numbers in the specified range as an {@code OptionalDouble}. * If the specified range is empty ({@code fromIndex == toIndex}, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the array, which must be a subtype of Number * @param a the array of elements to evaluate * @param fromIndex the start index of the range, inclusive * @param toIndex the end index of the range, exclusive * @return the average of the integer values of the provided numbers in the specified range as an {@code OptionalDouble} if the ranger is not empty, otherwise an empty {@code OptionalDouble} * @throws IndexOutOfBoundsException if the range is invalid: ({@code fromIndex < 0 || fromIndex > toIndex || toIndex > a.length}) * @see N#averageInt(Number[], int, int) */ public static OptionalDouble averageInt(final T[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { return averageInt(a, fromIndex, toIndex, Fn.numToInt()); } /** * Returns the average of the integer values extracted from the elements in the provided array by the input {@code func} function as an {@code OptionalDouble}. * If the array is {@code null} or empty, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the array * @param a the array of elements to evaluate * @param func the function to extract an integer value from each element * @return the average of the integer values if the array is not {@code null} or empty, otherwise an empty {@code OptionalDouble} * @see N#averageInt(Object[], ToIntFunction) */ public static OptionalDouble averageInt(final T[] a, final ToIntFunction func) { if (N.isEmpty(a)) { return OptionalDouble.empty(); } return averageInt(a, 0, a.length, func); } /** * Returns the average of the integer values extracted from the elements in the specified range by the input {@code func} function as an {@code OptionalDouble}. * If the specified range is empty ({@code fromIndex == toIndex}, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the array * @param a the array of elements to evaluate * @param fromIndex the start index of the range, inclusive * @param toIndex the end index of the range, exclusive * @param func the function to extract an integer value from each element * @return the average of the integer values of the provided numbers in the specified range as an {@code OptionalDouble} if the ranger is not empty, otherwise an empty {@code OptionalDouble} * @throws IndexOutOfBoundsException if the range is invalid: ({@code fromIndex < 0 || fromIndex > toIndex || toIndex > a.length}) * @see N#averageInt(Object[], int, int, ToIntFunction) */ public static OptionalDouble averageInt(final T[] a, final int fromIndex, final int toIndex, final ToIntFunction func) throws IndexOutOfBoundsException { N.checkFromToIndex(fromIndex, toIndex, N.len(a)); if (fromIndex == toIndex) { return OptionalDouble.empty(); } return OptionalDouble.of(N.averageInt(a, fromIndex, toIndex, func)); } /** * Returns the average of the integer values of the provided numbers in the specified range as an {@code OptionalDouble}. * If the specified range is empty ({@code fromIndex == toIndex}, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the collection, which must be a subtype of Number * @param c the collection of elements to evaluate * @param fromIndex the start index of the range, inclusive * @param toIndex the end index of the range, exclusive * @return the average of the integer values of the provided numbers in the specified range as an {@code OptionalDouble} if the ranger is not empty, otherwise an empty {@code OptionalDouble} * @throws IndexOutOfBoundsException if the range is invalid: ({@code fromIndex < 0 || fromIndex > toIndex || toIndex > a.length}) * @see N#averageInt(Collection, int, int) */ public static OptionalDouble averageInt(final Collection c, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { return averageInt(c, fromIndex, toIndex, Fn.numToInt()); } /** * Returns the average of the integer values extracted from the elements in the specified range by the input {@code func} function as an {@code OptionalDouble}. * If the specified range is empty ({@code fromIndex == toIndex}, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the collection * @param c the collection of elements to evaluate * @param fromIndex the start index of the range, inclusive * @param toIndex the end index of the range, exclusive * @param func the function to extract an integer value from each element * @return the average of the integer values of the provided numbers in the specified range as an {@code OptionalDouble} if the ranger is not empty, otherwise an empty {@code OptionalDouble} * @throws IndexOutOfBoundsException if the range is invalid: ({@code fromIndex < 0 || fromIndex > toIndex || toIndex > a.length}) * @see N#averageInt(Collection, int, int, ToIntFunction) */ public static OptionalDouble averageInt(final Collection c, final int fromIndex, final int toIndex, final ToIntFunction func) throws IndexOutOfBoundsException { N.checkFromToIndex(fromIndex, toIndex, N.size(c)); if (fromIndex == toIndex) { return OptionalDouble.empty(); } return OptionalDouble.of(N.averageInt(c, fromIndex, toIndex, func)); } /** * Returns the average of the integer values of the provided numbers as an {@code OptionalDouble}. * If the iterable is {@code null} or empty, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the iterable, which must be a subtype of Number * @param c the iterable of elements to evaluate * @return the average of the integer values if the iterable is not {@code null} or empty, otherwise an empty {@code OptionalDouble} * @see N#averageInt(Iterable) */ public static OptionalDouble averageInt(final Iterable c) { return averageInt(c, Fn.numToInt()); } /** * Returns the average of the integer values extracted from the elements in the provided iterable by the input {@code func} function as an {@code OptionalDouble}. * If the iterable is {@code null} or empty, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the iterable * @param c the iterable of elements to evaluate * @param func the function to extract an integer value from each element * @return the average of the integer values if the iterable is not {@code null} or empty, otherwise an empty {@code OptionalDouble} * @see N#averageInt(Iterable, ToIntFunction) */ public static OptionalDouble averageInt(final Iterable c, final ToIntFunction func) { final Iterator iter = c == null ? ObjIterator.empty() : c.iterator(); if (!iter.hasNext()) { return OptionalDouble.empty(); } return OptionalDouble.of(N.averageInt(c, func)); } /** * Returns the average of the long values of the provided numbers as an {@code OptionalDouble}. * If the array is {@code null} or empty, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the array, which must be a subtype of Number * @param a the array of elements to evaluate * @return the average of the long values if the array is not {@code null} or empty, otherwise an empty {@code OptionalDouble} * @see N#averageLong(Number[]) */ public static OptionalDouble averageLong(final T[] a) { return averageLong(a, Fn.numToLong()); } /** * Returns the average of the long values of the provided numbers in the specified range as an {@code OptionalDouble}. * If the specified range is empty ({@code fromIndex == toIndex}, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the array, which must be a subtype of Number * @param a the array of elements to evaluate * @param fromIndex the start index of the range, inclusive * @param toIndex the end index of the range, exclusive * @return the average of the long values of the provided numbers in the specified range as an {@code OptionalDouble} if the ranger is not empty, otherwise an empty {@code OptionalDouble} * @throws IndexOutOfBoundsException if the range is invalid: ({@code fromIndex < 0 || fromIndex > toIndex || toIndex > a.length}) * @see N#averageLong(Number[], int, int) */ public static OptionalDouble averageLong(final T[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { return averageLong(a, fromIndex, toIndex, Fn.numToLong()); } /** * Returns the average of the long values extracted from the elements in the provided array by the input {@code func} function as an {@code OptionalDouble}. * If the array is {@code null} or empty, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the array * @param a the array of elements to evaluate * @param func the function to extract a long value from each element * @return the average of the long values if the array is not {@code null} or empty, otherwise an empty {@code OptionalDouble} * @see N#averageLong(Object[], ToLongFunction) */ public static OptionalDouble averageLong(final T[] a, final ToLongFunction func) { if (N.isEmpty(a)) { return OptionalDouble.empty(); } return averageLong(a, 0, a.length, func); } /** * Returns the average of the long values extracted from the elements in the specified range by the input {@code func} function as an {@code OptionalDouble}. * If the specified range is empty ({@code fromIndex == toIndex}, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the array * @param a the array of elements to evaluate * @param fromIndex the start index of the range, inclusive * @param toIndex the end index of the range, exclusive * @param func the function to extract a long value from each element * @return the average of the long values of the provided numbers in the specified range as an {@code OptionalDouble} if the ranger is not empty, otherwise an empty {@code OptionalDouble} * @throws IndexOutOfBoundsException if the range is invalid: ({@code fromIndex < 0 || fromIndex > toIndex || toIndex > a.length}) * @see N#averageLong(Object[], int, int, ToLongFunction) */ public static OptionalDouble averageLong(final T[] a, final int fromIndex, final int toIndex, final ToLongFunction func) throws IndexOutOfBoundsException { N.checkFromToIndex(fromIndex, toIndex, N.len(a)); if (fromIndex == toIndex) { return OptionalDouble.empty(); } return OptionalDouble.of(N.averageLong(a, fromIndex, toIndex, func)); } /** * Returns the average of the long values of the provided numbers in the specified range as an {@code OptionalDouble}. * If the specified range is empty ({@code fromIndex == toIndex}, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the collection, which must be a subtype of Number * @param c the collection of elements to evaluate * @param fromIndex the start index of the range, inclusive * @param toIndex the end index of the range, exclusive * @return the average of the long values of the provided numbers in the specified range as an {@code OptionalDouble} if the ranger is not empty, otherwise an empty {@code OptionalDouble} * @throws IndexOutOfBoundsException if the range is invalid: ({@code fromIndex < 0 || fromIndex > toIndex || toIndex > a.length}) * @see N#averageLong(Collection, int, int) */ public static OptionalDouble averageLong(final Collection c, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { return averageLong(c, fromIndex, toIndex, Fn.numToLong()); } /** * Returns the average of the integer values extracted from the elements in the specified range by the input {@code func} function as an {@code OptionalDouble}. * If the specified range is empty ({@code fromIndex == toIndex}, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the array * @param c the collection of elements to evaluate * @param fromIndex the start index of the range, inclusive * @param toIndex the end index of the range, exclusive * @param func the function to extract an integer value from each element * @return the average of the integer values of the provided numbers in the specified range as an {@code OptionalDouble} if the ranger is not empty, otherwise an empty {@code OptionalDouble} * @throws IndexOutOfBoundsException if the range is invalid: ({@code fromIndex < 0 || fromIndex > toIndex || toIndex > a.length}) * @see N#averageLong(Object[], int, int, ToLongFunction) */ public static OptionalDouble averageLong(final Collection c, final int fromIndex, final int toIndex, final ToLongFunction func) throws IndexOutOfBoundsException { N.checkFromToIndex(fromIndex, toIndex, N.size(c)); if (fromIndex == toIndex) { return OptionalDouble.empty(); } return OptionalDouble.of(N.averageLong(c, fromIndex, toIndex, func)); } /** * Returns the average of the long values of the provided numbers as an {@code OptionalDouble}. * If the iterable is {@code null} or empty, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the iterable, which must be a subtype of Number * @param c the iterable of elements to evaluate * @return the average of the long values if the iterable is not {@code null} or empty, otherwise an empty {@code OptionalDouble} * @see N#averageLong(Iterable) */ public static OptionalDouble averageLong(final Iterable c) { return averageLong(c, Fn.numToLong()); } /** * Returns the average of the long values extracted from the elements in the provided iterable by the input {@code func} function as an {@code OptionalDouble}. * If the iterable is {@code null} or empty, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the iterable * @param c the iterable of elements to evaluate * @param func the function to extract a long value from each element * @return the average of the long values if the iterable is not {@code null} or empty, otherwise an empty {@code OptionalDouble} * @see N#averageLong(Iterable, ToLongFunction) */ public static OptionalDouble averageLong(final Iterable c, final ToLongFunction func) { final Iterator iter = c == null ? ObjIterator.empty() : c.iterator(); if (!iter.hasNext()) { return OptionalDouble.empty(); } return OptionalDouble.of(N.averageLong(c, func)); } /** * Returns the average of the double values of the provided numbers as an {@code OptionalDouble}. * If the array is {@code null} or empty, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the array, which must be a subtype of Number * @param a the array of elements to evaluate * @return the average of the double values if the array is not {@code null} or empty, otherwise an empty {@code OptionalDouble} * @see N#averageDouble(Number[]) */ public static OptionalDouble averageDouble(final T[] a) { return averageDouble(a, Fn.numToDouble()); } /** * Returns the average of the double values of the provided numbers in the specified range as an {@code OptionalDouble}. * If the specified range is empty ({@code fromIndex == toIndex}, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the array, which must be a subtype of Number * @param a the array of elements to evaluate * @param fromIndex the start index of the range, inclusive * @param toIndex the end index of the range, exclusive * @return the average of the double values of the provided numbers in the specified range as an {@code OptionalDouble} if the ranger is not empty, otherwise an empty {@code OptionalDouble} * @throws IndexOutOfBoundsException if the range is invalid: ({@code fromIndex < 0 || fromIndex > toIndex || toIndex > a.length}) * @see N#averageDouble(Number[], int, int) */ public static OptionalDouble averageDouble(final T[] a, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { return averageDouble(a, fromIndex, toIndex, Fn.numToDouble()); } /** * Returns the average of the double values extracted from the elements in the provided array by the input {@code func} function as an {@code OptionalDouble}. * If the array is {@code null} or empty, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the array * @param a the array of elements to evaluate * @param func the function to extract a double value from each element * @return the average of the double values if the array is not {@code null} or empty, otherwise an empty {@code OptionalDouble} * @see N#averageDouble(Object[], ToDoubleFunction) */ public static OptionalDouble averageDouble(final T[] a, final ToDoubleFunction func) { if (N.isEmpty(a)) { return OptionalDouble.empty(); } return averageDouble(a, 0, a.length, func); } /** * Returns the average of the double values extracted from the elements in the specified range by the input {@code func} function as an {@code OptionalDouble}. * If the specified range is empty ({@code fromIndex == toIndex}, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the array * @param a the array of elements to evaluate * @param fromIndex the start index of the range, inclusive * @param toIndex the end index of the range, exclusive * @param func the function to extract a double value from each element * @return the average of the double values of the provided numbers in the specified range as an {@code OptionalDouble} if the ranger is not empty, otherwise an empty {@code OptionalDouble} * @throws IndexOutOfBoundsException if the range is invalid: ({@code fromIndex < 0 || fromIndex > toIndex || toIndex > a.length}) * @see N#averageDouble(Object[], int, int, ToDoubleFunction) */ public static OptionalDouble averageDouble(final T[] a, final int fromIndex, final int toIndex, final ToDoubleFunction func) throws IndexOutOfBoundsException { N.checkFromToIndex(fromIndex, toIndex, N.len(a)); if (fromIndex == toIndex) { return OptionalDouble.empty(); } final KahanSummation summation = new KahanSummation(); for (int i = fromIndex; i < toIndex; i++) { summation.add(func.applyAsDouble(a[i])); } return summation.average(); } /** * Returns the average of the double values of the provided numbers in the specified range as an {@code OptionalDouble}. * If the specified range is empty ({@code fromIndex == toIndex}, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the collection, which must be a subtype of Number * @param c the collection of elements to evaluate * @param fromIndex the start index of the range, inclusive * @param toIndex the end index of the range, exclusive * @return the average of the double values of the provided numbers in the specified range as an {@code OptionalDouble} if the ranger is not empty, otherwise an empty {@code OptionalDouble} * @throws IndexOutOfBoundsException if the range is invalid: ({@code fromIndex < 0 || fromIndex > toIndex || toIndex > a.length}) * @see N#averageDouble(Collection, int, int) */ public static OptionalDouble averageDouble(final Collection c, final int fromIndex, final int toIndex) throws IndexOutOfBoundsException { return averageDouble(c, fromIndex, toIndex, Fn.numToDouble()); } /** * Returns the average of the double values extracted from the elements in the specified range by the input {@code func} function as an {@code OptionalDouble}. * If the specified range is empty ({@code fromIndex == toIndex}, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the collection * @param c the collection of elements to evaluate * @param fromIndex the start index of the range, inclusive * @param toIndex the end index of the range, exclusive * @param func the function to extract a double value from each element * @return the average of the double values of the provided numbers in the specified range as an {@code OptionalDouble} if the ranger is not empty, otherwise an empty {@code OptionalDouble} * @throws IndexOutOfBoundsException if the range is invalid: ({@code fromIndex < 0 || fromIndex > toIndex || toIndex > a.length}) * @see N#averageDouble(Object[], int, int, ToDoubleFunction) */ public static OptionalDouble averageDouble(final Collection c, final int fromIndex, final int toIndex, final ToDoubleFunction func) throws IndexOutOfBoundsException { N.checkFromToIndex(fromIndex, toIndex, N.size(c)); if (fromIndex == toIndex) { return OptionalDouble.empty(); } final KahanSummation summation = new KahanSummation(); if (c instanceof List && c instanceof RandomAccess) { final List list = (List) c; for (int i = fromIndex; i < toIndex; i++) { summation.add(func.applyAsDouble(list.get(i))); } } else { int idx = 0; for (final T e : c) { if (idx++ < fromIndex) { continue; } summation.add(func.applyAsDouble(e)); if (idx >= toIndex) { break; } } } return summation.average(); } /** * Returns the average of the double values of the provided numbers as an {@code OptionalDouble}. * If the iterable is {@code null} or empty, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the iterable, which must be a subtype of Number * @param c the iterable of elements to evaluate * @return the average of the double values if the iterable is not {@code null} or empty, otherwise an empty {@code OptionalDouble} * @see N#averageDouble(Iterable) */ public static OptionalDouble averageDouble(final Iterable c) { return averageDouble(c, Fn.numToDouble()); } /** * Returns the average of the double values extracted from the elements in the provided iterable by the input {@code func} function as an {@code OptionalDouble}. * If the iterable is {@code null} or empty, it returns an empty {@code OptionalDouble}. * * @param the type of the elements in the iterable * @param c the iterable of elements to evaluate * @param func the function to extract a double value from each element * @return the average of the double values if the iterable is not {@code null} or empty, otherwise an empty {@code OptionalDouble} * @see N#averageDouble(Iterable, ToDoubleFunction) */ public static OptionalDouble averageDouble(final Iterable c, final ToDoubleFunction func) { if (c == null) { return OptionalDouble.empty(); } final KahanSummation summation = new KahanSummation(); for (final T e : c) { summation.add(func.applyAsDouble(e)); } return summation.average(); } /** * Returns the average of the BigInteger values of the provided numbers as an {@code Optional}. * If the iterable is {@code null} or empty, it returns an empty {@code Optional}. * * @param c the iterable of elements to evaluate * @return the average of the BigInteger values if the iterable is not {@code null} or empty, otherwise an empty {@code Optional} * @see N#averageBigInteger(Iterable) */ public static Optional averageBigInteger(final Iterable c) { return averageBigInteger(c, Fn.identity()); } /** * Returns the average of the BigInteger values extracted from the elements in the provided iterable by the input {@code func} function as an {@code Optional}. * If the iterable is {@code null} or empty, it returns an empty {@code Optional}. * * @param the type of the elements in the iterable * @param c the iterable of elements to evaluate * @param func the function to extract a BigInteger value from each element * @return the average of the BigInteger values if the iterable is not {@code null} or empty, otherwise an empty {@code Optional} * @see N#averageBigInteger(Iterable, Function) */ public static Optional averageBigInteger(final Iterable c, final Function func) { final Iterator iter = c == null ? ObjIterator.empty() : c.iterator(); if (!iter.hasNext()) { return Optional.empty(); } return Optional.of(N.averageBigInteger(c, func)); } /** * Returns the average of the BigDecimal values of the provided numbers as an {@code Optional}. * If the iterable is {@code null} or empty, it returns an empty {@code Optional}. * * @param c the iterable of elements to evaluate * @return the average of the BigDecimal values if the iterable is not {@code null} or empty, otherwise an empty {@code Optional} * @see N#averageBigDecimal(Iterable) */ public static Optional averageBigDecimal(final Iterable c) { return averageBigDecimal(c, Fn.identity()); } /** * Returns the average of the BigDecimal values extracted from the elements in the provided iterable by the input {@code func} function as an {@code Optional}. * If the iterable is {@code null} or empty, it returns an empty {@code Optional}. * * @param the type of the elements in the iterable * @param c the iterable of elements to evaluate * @param func the function to extract a BigDecimal value from each element * @return the average of the BigDecimal values if the iterable is not {@code null} or empty, otherwise an empty {@code Optional} * @see N#averageBigDecimal(Iterable, Function) */ public static Optional averageBigDecimal(final Iterable c, final Function func) { final Iterator iter = c == null ? ObjIterator.empty() : c.iterator(); if (!iter.hasNext()) { return Optional.empty(); } return Optional.of(N.averageBigDecimal(c, func)); } /** * Returns the index of the first occurrence of the specified value in the provided array as an {@code OptionalInt}. * If the array is {@code null} or doesn't contain the specified value, it returns an empty {@code OptionalInt}. * * @param a the array to search * @param valueToFind the value to find in the array * @return an {@code OptionalInt} containing the index of the first occurrence of the specified value if found, otherwise an empty {@code OptionalInt} * @see N#indexOf(Object[], Object) * @see Index#of(Object[], Object) */ public static OptionalInt indexOf(final Object[] a, final Object valueToFind) { return Index.of(a, valueToFind); } /** * Returns the index of the first occurrence of the specified value in the provided collection as an {@code OptionalInt}. * If the collection is {@code null} or doesn't contain the specified value, it returns an empty {@code OptionalInt}. * * @param c the collection to search * @param valueToFind the value to find in the collection * @return an {@code OptionalInt} containing the index of the first occurrence of the specified value if found, otherwise an empty {@code OptionalInt} * @see N#indexOf(Collection, Object) * @see Index#of(Collection, Object) */ public static OptionalInt indexOf(final Collection c, final Object valueToFind) { return Index.of(c, valueToFind); } /** * Returns the index of the last occurrence of the specified value in the provided array as an {@code OptionalInt}. * If the array is {@code null} or doesn't contain the specified value, it returns an empty {@code OptionalInt}. * * @param a the array to search * @param valueToFind the value to find in the array * @return an {@code OptionalInt} containing the index of the last occurrence of the specified value if found, otherwise an empty {@code OptionalInt} * @see N#lastIndexOf(Object[], Object) * @see Index#last(Object[], Object) */ public static OptionalInt lastIndexOf(final Object[] a, final Object valueToFind) { return Index.last(a, valueToFind); } /** * Returns the index of the last occurrence of the specified value in the provided collection as an {@code OptionalInt}. * If the collection is {@code null} or doesn't contain the specified value, it returns an empty {@code OptionalInt}. * * @param c the collection to search * @param valueToFind the value to find in the collection * @return an {@code OptionalInt} containing the index of the last occurrence of the specified value if found, otherwise an empty {@code OptionalInt} * @see N#lastIndexOf(Collection, Object) * @see Index#last(Collection, Object) */ public static OptionalInt lastIndexOf(final Collection c, final Object valueToFind) { return Index.last(c, valueToFind); } /** * Returns the first element in the provided array that satisfies the given {@code predicateForFirst}, * or if no such element is found, returns the last element that satisfies the {@code predicateForLast}. * If the array is {@code null} or doesn't contain any element that satisfies the predicates, it returns an empty {@code Nullable}. * * @param the type of the elements in the array * @param a the array to search * @param predicateForFirst the predicate to test for the first element * @param predicateForLast the predicate to test for the last element * @return a {@code Nullable} containing the first element satisfying {@code predicateForFirst} if found, * otherwise the last element satisfying {@code predicateForLast} if found, otherwise an empty {@code Nullable} * @see N#findFirst(Object[], Predicate) * @see N#findLast(Object[], Predicate) */ public static Nullable findFirstOrLast(final T[] a, final Predicate predicateForFirst, final Predicate predicateForLast) { if (N.isEmpty(a)) { return Nullable.empty(); } final Nullable res = N.findFirst(a, predicateForFirst); return res.isPresent() ? res : N.findLast(a, predicateForLast); } /** * Returns the first element in the provided collection that satisfies the given {@code predicateForFirst}, * or if no such element is found, returns the last element that satisfies the {@code predicateForLast}. * If the collection is {@code null} or doesn't contain any element that satisfies the predicates, it returns an empty {@code Nullable}. * * @param the type of the elements in the collection * @param c the collection to search * @param predicateForFirst the predicate to test for the first element * @param predicateForLast the predicate to test for the last element * @return a {@code Nullable} containing the first element satisfying {@code predicateForFirst} if found, * otherwise the last element satisfying {@code predicateForLast} if found, otherwise an empty {@code Nullable} * @see N#findFirst(Iterable, Predicate) * @see N#findLast(Iterable, Predicate) */ public static Nullable findFirstOrLast(final Collection c, final Predicate predicateForFirst, final Predicate predicateForLast) { if (N.isEmpty(c)) { return Nullable.empty(); } final Nullable res = N.findFirst(c, predicateForFirst); return res.isPresent() ? res : N.findLast(c, predicateForLast); } /** * Returns the index of the first element in the provided array that satisfies the given {@code predicateForFirst}, * or if no such element is found, returns the index of the last element that satisfies the {@code predicateForLast}. * If the array is {@code null} or doesn't contain any element that satisfies the predicates, it returns an empty {@code OptionalInt}. * * @param the type of the elements in the array * @param a the array to search * @param predicateForFirst the predicate to test for the first element * @param predicateForLast the predicate to test for the last element * @return an {@code OptionalInt} containing the index of the first element satisfying {@code predicateForFirst} if found, * otherwise the index of the last element satisfying {@code predicateForLast} if found, otherwise an empty {@code OptionalInt} * @see N#findFirstIndex(Object[], Predicate) * @see N#findLastIndex(Object[], Predicate) */ public static OptionalInt findFirstOrLastIndex(final T[] a, final Predicate predicateForFirst, final Predicate predicateForLast) { if (N.isEmpty(a)) { return OptionalInt.empty(); } final OptionalInt res = N.findFirstIndex(a, predicateForFirst); return res.isPresent() ? res : N.findLastIndex(a, predicateForLast); } /** * Returns the index of the first element in the provided collection that satisfies the given {@code predicateForFirst}, * or if no such element is found, returns the index of the last element that satisfies the {@code predicateForLast}. * If the collection is {@code null} or doesn't contain any element that satisfies the predicates, it returns an empty {@code OptionalInt}. * * @param the type of the elements in the collection * @param c the collection to search * @param predicateForFirst the predicate to test for the first element * @param predicateForLast the predicate to test for the last element * @return an {@code OptionalInt} containing the index of the first element satisfying {@code predicateForFirst} if found, * otherwise the index of the last element satisfying {@code predicateForLast} if found, otherwise an empty {@code OptionalInt} * @see N#findFirstIndex(Collection, Predicate) * @see N#findLastIndex(Collection, Predicate) */ public static OptionalInt findFirstOrLastIndex(final Collection c, final Predicate predicateForFirst, final Predicate predicateForLast) { if (N.isEmpty(c)) { return OptionalInt.empty(); } final OptionalInt res = N.findFirstIndex(c, predicateForFirst); return res.isPresent() ? res : N.findLastIndex(c, predicateForLast); } /** * Returns a pair of {@code Nullable} objects containing the first and last elements in the provided array that satisfy the given {@code predicate}. * If the array is {@code null} or doesn't contain any element that satisfies the predicate, it returns a pair of empty {@code Nullable} objects. * * @param the type of the elements in the array * @param a the array to search * @param predicate the predicate to test for the first and last elements * @return a {@code Pair} containing a {@code Nullable} for the first element satisfying {@code predicate} if found and a {@code Nullable} for the last element satisfying {@code predicate} if found, * otherwise a {@code Pair} of empty {@code Nullable} objects * @see #findFirstAndLast(Object[], Predicate, Predicate) * @see #findFirstOrLast(Object[], Predicate, Predicate) * @see N#findFirst(Object[], Predicate) * @see N#findLast(Object[], Predicate) */ public static Pair, Nullable> findFirstAndLast(final T[] a, final Predicate predicate) { return findFirstAndLast(a, predicate, predicate); } /** * Returns a pair of {@code Nullable} objects containing the first and last elements in the provided array that satisfy the given predicates. * If the array is {@code null} or doesn't contain any element that satisfies the predicates, it returns a pair of empty {@code Nullable} objects. * * @param the type of the elements in the array * @param a the array to search * @param predicateForFirst the predicate to test for the first element * @param predicateForLast the predicate to test for the last element * @return a {@code Pair} containing a {@code Nullable} for the first element satisfying {@code predicateForFirst} if found and a {@code Nullable} for the last element satisfying {@code predicateForLast} if found, * otherwise a {@code Pair} of empty {@code Nullable} objects * @see #findFirstAndLast(Object[], Predicate) * @see #findFirstOrLast(Object[], Predicate, Predicate) * @see N#findFirst(Object[], Predicate) * @see N#findLast(Object[], Predicate) */ public static Pair, Nullable> findFirstAndLast(final T[] a, final Predicate predicateForFirst, final Predicate predicateForLast) { if (N.isEmpty(a)) { return Pair.of(Nullable.empty(), Nullable.empty()); } return Pair.of(N.findFirst(a, predicateForFirst), N.findLast(a, predicateForLast)); } /** * Returns a pair of {@code Nullable} objects containing the first and last elements in the provided collection that satisfy the given {@code predicate}. * If the collection is {@code null} or doesn't contain any element that satisfies the predicate, it returns a pair of empty {@code Nullable} objects. * * @param the type of the elements in the collection * @param c the collection to search * @param predicate the predicate to test for the first and last elements * @return a {@code Pair} containing a {@code Nullable} for the first element satisfying {@code predicate} if found and a {@code Nullable} for the last element satisfying {@code predicate} if found, * otherwise a {@code Pair} of empty {@code Nullable} objects * @see #findFirstAndLast(Collection, Predicate, Predicate) * @see #findFirstOrLast(Collection, Predicate, Predicate) * @see N#findFirst(Iterable, Predicate) * @see N#findLast(Iterable, Predicate) */ public static Pair, Nullable> findFirstAndLast(final Collection c, final Predicate predicate) { return findFirstAndLast(c, predicate, predicate); } /** * Returns a pair of {@code Nullable} objects containing the first and last elements in the provided collection that satisfy the given predicates. * If the collection is {@code null} or doesn't contain any element that satisfies the predicates, it returns a pair of empty {@code Nullable} objects. * * @param the type of the elements in the collection * @param c the collection to search * @param predicateForFirst the predicate to test for the first element * @param predicateForLast the predicate to test for the last element * @return a {@code Pair} containing a {@code Nullable} for the first element satisfying {@code predicateForFirst} if found and a {@code Nullable} for the last element satisfying {@code predicateForLast} if found, * otherwise a {@code Pair} of empty {@code Nullable} objects * @see #findFirstAndLast(Collection, Predicate) * @see #findFirstOrLast(Collection, Predicate, Predicate) * @see N#findFirst(Iterable, Predicate) * @see N#findLast(Iterable, Predicate) */ public static Pair, Nullable> findFirstAndLast(final Collection c, final Predicate predicateForFirst, final Predicate predicateForLast) { if (N.isEmpty(c)) { return Pair.of(Nullable.empty(), Nullable.empty()); } return Pair.of(N.findFirst(c, predicateForFirst), N.findLast(c, predicateForLast)); } /** * Returns a pair of OptionalInt objects containing the indices of the first and last elements in the provided array that satisfy the given {@code predicate}. * If the array is {@code null} or doesn't contain any element that satisfies the predicate, it returns a pair of empty {@code OptionalInt} objects. * * @param the type of the elements in the array * @param a the array to search * @param predicate the predicate to test for the first and last elements * @return a {@code Pair} containing an {@code OptionalInt} for the index of the first element satisfying {@code predicate} if found and an {@code OptionalInt} for the index of the last element satisfying {@code predicate} if found, * otherwise a {@code Pair} of empty {@code OptionalInt} objects * @see #findFirstAndLastIndex(Object[], Predicate, Predicate) * @see #findFirstOrLastIndex(Object[], Predicate, Predicate) * @see N#findFirstIndex(Object[], Predicate) * @see N#findLastIndex(Object[], Predicate) */ public static Pair findFirstAndLastIndex(final T[] a, final Predicate predicate) { return findFirstAndLastIndex(a, predicate, predicate); } /** * Returns a pair of OptionalInt objects containing the indices of the first and last elements in the provided array that satisfy the given predicates. * If the array is {@code null} or doesn't contain any element that satisfies the predicates, it returns a pair of empty {@code OptionalInt} objects. * * @param the type of the elements in the array * @param a the array to search * @param predicateForFirst the predicate to test for the first element * @param predicateForLast the predicate to test for the last element * @return a {@code Pair} containing an {@code OptionalInt} for the index of the first element satisfying {@code predicateForFirst} if found and an {@code OptionalInt} for the index of the last element satisfying {@code predicateForLast} if found, * otherwise a {@code Pair} of empty {@code OptionalInt} objects * @see #findFirstAndLastIndex(Object[], Predicate) * @see #findFirstOrLastIndex(Object[], Predicate, Predicate) * @see N#findFirstIndex(Object[], Predicate) * @see N#findLastIndex(Object[], Predicate) */ public static Pair findFirstAndLastIndex(final T[] a, final Predicate predicateForFirst, final Predicate predicateForLast) { if (N.isEmpty(a)) { return Pair.of(OptionalInt.empty(), OptionalInt.empty()); } return Pair.of(N.findFirstIndex(a, predicateForFirst), N.findLastIndex(a, predicateForLast)); } /** * Returns a pair of OptionalInt objects containing the indices of the first and last elements in the provided collection that satisfy the given {@code predicate}. * If the collection is {@code null} or doesn't contain any element that satisfies the predicate, it returns a pair of empty {@code OptionalInt} objects. * * @param the type of the elements in the collection * @param c the collection to search * @param predicate the predicate to test for the first and last elements * @return a {@code Pair} containing an {@code OptionalInt} for the index of the first element satisfying {@code predicate} if found and an {@code OptionalInt} for the index of the last element satisfying {@code predicate} if found, * otherwise a {@code Pair} of empty {@code OptionalInt} objects * @see #findFirstAndLastIndex(Collection, Predicate, Predicate) * @see #findFirstOrLastIndex(Collection, Predicate, Predicate) * @see N#findFirstIndex(Collection, Predicate) * @see N#findLastIndex(Collection, Predicate) */ public static Pair findFirstAndLastIndex(final Collection c, final Predicate predicate) { return findFirstAndLastIndex(c, predicate, predicate); } /** * Returns a pair of OptionalInt objects containing the indices of the first and last elements in the provided collection that satisfy the given predicates. * If the collection is {@code null} or doesn't contain any element that satisfies the predicates, it returns a pair of empty {@code OptionalInt} objects. * * @param the type of the elements in the collection * @param c the collection to search * @param predicateForFirst the predicate to test for the first element * @param predicateForLast the predicate to test for the last element * @return a {@code Pair} containing an {@code OptionalInt} for the index of the first element satisfying {@code predicateForFirst} if found and an {@code OptionalInt} for the index of the last element satisfying {@code predicateForLast} if found, * otherwise a {@code Pair} of empty {@code OptionalInt} objects * @see #findFirstAndLastIndex(Collection, Predicate) * @see #findFirstOrLastIndex(Collection, Predicate, Predicate) * @see N#findFirstIndex(Collection, Predicate) * @see N#findLastIndex(Collection, Predicate) */ public static Pair findFirstAndLastIndex(final Collection c, final Predicate predicateForFirst, final Predicate predicateForLast) { if (N.isEmpty(c)) { return Pair.of(OptionalInt.empty(), OptionalInt.empty()); } return Pair.of(N.findFirstIndex(c, predicateForFirst), N.findLastIndex(c, predicateForLast)); } /** * Fills the specified Object array with the values provided by the specified supplier. * * @param a the Object array to be filled * @param supplier provider of the value to fill the array with * @see Arrays#fill(Object[], Object) * @see N#setAll(Object[], IntFunction) * @see N#replaceAll(Object[], UnaryOperator) * @see N#fill(Object[], Object) * @see N#fill(Object[], int, int, Object) */ @Beta public static void fill(final T[] a, final Supplier supplier) { if (N.isEmpty(a)) { return; } for (int i = 0, len = a.length; i < len; i++) { a[i] = supplier.get(); } } /** * Fills the specified Object array with the values provided by the specified supplier 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 supplier provider of the 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 N#fill(Object[], Object) * @see N#fill(Object[], int, int, Object) */ @Beta public static void fill(final T[] a, final int fromIndex, final int toIndex, final Supplier supplier) { N.checkFromToIndex(fromIndex, toIndex, N.len(a)); if (fromIndex == toIndex) { return; } for (int i = fromIndex; i < toIndex; i++) { a[i] = supplier.get(); } } /** * Fills the specified list with values provided by the specified supplier. * * @param the type of elements in the list * @param list the list to be filled * @param supplier provider of the value to fill the list with * @throws IllegalArgumentException if the specified list is null * @see N#fill(List, Object) * @see N#fill(List, int, int, Object) * @see N#setAll(List, java.util.function.IntFunction) * @see N#replaceAll(List, java.util.function.UnaryOperator) * @see N#padLeft(List, int, Object) * @see N#padRight(Collection, int, Object) */ @Beta public static void fill(final List list, final Supplier supplier) throws IllegalArgumentException { N.checkArgNotNull(list, cs.list); fill(list, 0, list.size(), supplier); } /** * Fills the specified list with the specified with values provided by the specified supplier 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 supplier provider of 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 N#fill(List, Object) * @see N#fill(List, int, int, Object) * @see N#setAll(List, java.util.function.IntFunction) * @see N#replaceAll(List, java.util.function.UnaryOperator) * @see N#padLeft(List, int, Object) * @see N#padRight(Collection, int, Object) */ @Beta public static void fill(final List list, final int fromIndex, final int toIndex, final Supplier supplier) throws IllegalArgumentException, IndexOutOfBoundsException { N.checkArgNotNull(list, cs.list); N.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, supplier.get()); } } else { for (int i = size; i < fromIndex; i++) { list.add(null); } } for (int i = 0, len = toIndex - list.size(); i < len; i++) { list.add(supplier.get()); } } else { if (toIndex - fromIndex < CommonUtil.FILL_THRESHOLD || list instanceof RandomAccess) { for (int i = fromIndex; i < toIndex; i++) { list.set(i, supplier.get()); } } else { final ListIterator itr = list.listIterator(fromIndex); for (int i = fromIndex; i < toIndex; i++) { itr.next(); itr.set(supplier.get()); } } } } /** *

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

* * Returns a reversed view of the specified list. For example, {@code * reverse(Arrays.asList(1, 2, 3))} returns a list containing {@code 3, 2, 1}. The returned * list is backed by this list, so changes in the returned list are reflected in this list, and * vice versa. The returned list supports all the optional list operations supported by this * list. * *

The returned list is random-access if the specified list is random access.

* * @param the type of elements in the list * @param list the list to be reversed * @return a reversed view of the specified list * @see N#reverse(List) * @see N#reverse(Collection) * @see N#reverseToList(Collection) */ public static List reverse(final List list) { if (list instanceof ImmutableList) { // Avoid nullness warnings. final List reversed = ((ImmutableList) list).reverse(); return (List) reversed; } else if (list instanceof ReverseList) { return ((ReverseList) list).getForwardList(); } else if (list instanceof RandomAccess) { return new RandomAccessReverseList<>(list); } else { return new ReverseList<>(list); } } // Copied from Google Guava under Apache License v2.0 and may be modified. private static sealed class ReverseList extends AbstractList permits RandomAccessReverseList { private final List forwardList; ReverseList(final List forwardList) { this.forwardList = N.checkArgNotNull(forwardList); } List getForwardList() { return forwardList; } private int reverseIndex(final int index) { final int size = size(); N.checkElementIndex(index, size); return (size - 1) - index; } private int reversePosition(final int index) { final int size = size(); N.checkPositionIndex(index, size); return size - index; } @Override public void add(final int index, final T element) { forwardList.add(reversePosition(index), element); } @Override public void clear() { forwardList.clear(); } @Override public T remove(final int index) { return forwardList.remove(reverseIndex(index)); } @Override protected void removeRange(final int fromIndex, final int toIndex) { subList(fromIndex, toIndex).clear(); } @Override public T set(final int index, final T element) { return forwardList.set(reverseIndex(index), element); } @Override public T get(final int index) { return forwardList.get(reverseIndex(index)); } @Override public int size() { return forwardList.size(); } @Override public List subList(final int fromIndex, final int toIndex) { N.checkFromToIndex(fromIndex, toIndex, size()); return reverse(forwardList.subList(reversePosition(toIndex), reversePosition(fromIndex))); } @Override public Iterator iterator() { return listIterator(); } @Override public ListIterator listIterator(final int index) { final int start = reversePosition(index); final ListIterator forwardIterator = forwardList.listIterator(start); return new ListIterator<>() { boolean canRemoveOrSet; @Override public void add(final T e) { forwardIterator.add(e); forwardIterator.previous(); canRemoveOrSet = false; } @Override public boolean hasNext() { return forwardIterator.hasPrevious(); } @Override public boolean hasPrevious() { return forwardIterator.hasNext(); } @Override public T next() { if (!hasNext()) { throw new NoSuchElementException(); } canRemoveOrSet = true; return forwardIterator.previous(); } @Override public int nextIndex() { return reversePosition(forwardIterator.nextIndex()); } @Override public T previous() { if (!hasPrevious()) { throw new NoSuchElementException(); } canRemoveOrSet = true; return forwardIterator.next(); } @Override public int previousIndex() { return nextIndex() - 1; } @Override public void remove() { checkRemove(canRemoveOrSet); forwardIterator.remove(); canRemoveOrSet = false; } @Override public void set(final T e) { N.checkState(canRemoveOrSet); forwardIterator.set(e); } }; } } // Copied from Google Guava under Apache License v2.0 and may be modified. private static final class RandomAccessReverseList extends ReverseList implements RandomAccess { RandomAccessReverseList(final List forwardList) { super(forwardList); } } static void checkRemove(final boolean canRemove) { N.checkState(canRemove, "no calls to next() since the last call to remove()"); } public abstract static class SetView extends ImmutableSet { SetView(final Set set) { super(set); } /** * * @param * @param set * @return */ public > S copyInto(final S set) { set.addAll(this); return set; } } /** * Returns an unmodifiable view of the union of two sets. The returned set contains all * elements that are contained in either backing set. Iterating over the returned set iterates * first over all the elements of {@code set1}, then over each element of {@code set2}, in order, * that is not contained in {@code set1}. * *

Results are undefined if {@code set1} and {@code set2} are sets based on different * equivalence relations (as {@link HashSet}, {@link TreeSet}, and the {@link Map#keySet} of an * {@code IdentityHashMap} all are). * * @param * @param set1 * @param set2 * @return * @throws IllegalArgumentException */ public static SetView union(final Set set1, final Set set2) throws IllegalArgumentException { // N.checkArgNotNull(set1, "set1"); // N.checkArgNotNull(set2, "set2"); Set tmp = null; if (N.isEmpty(set1)) { tmp = N.isEmpty(set2) ? N.emptySet() : set2; } else if (N.isEmpty(set2)) { tmp = set1; } else { tmp = new AbstractSet<>() { @Override public ObjIterator iterator() { return new ObjIterator<>() { private final Iterator iter1 = set1.iterator(); private final Iterator iter2 = set2.iterator(); private final E NONE = (E) N.NULL_MASK; //NOSONAR private E next = NONE; private E tmp = null; @Override public boolean hasNext() { if (iter1.hasNext() || next != NONE) { return true; } while (iter2.hasNext()) { next = iter2.next(); if (!set1.contains(next)) { return true; } } next = NONE; return false; } @Override public E next() { if (!hasNext()) { throw new NoSuchElementException(InternalUtil.ERROR_MSG_FOR_NO_SUCH_EX); } if (iter1.hasNext()) { return iter1.next(); } else { tmp = next; next = NONE; return tmp; } } }; } @Override public boolean contains(final Object object) { return set1.contains(object) || set2.contains(object); } @Override public int size() { int size = set1.size(); for (final E e : set2) { if (!set1.contains(e)) { size++; } } return size; } @Override public boolean isEmpty() { return set1.isEmpty() && set2.isEmpty(); } }; } return new SetView<>(tmp) { @Override public > S copyInto(final S set) { set.addAll(set1); set.addAll(set2); return set; } }; } /** * Returns an unmodifiable view of the intersection of two sets. The returned set contains * all elements that are contained by both backing sets. The iteration order of the returned set * matches that of {@code set1}. * *

Results are undefined if {@code set1} and {@code set2} are sets based on different * equivalence relations (as {@code HashSet}, {@code TreeSet}, and the keySet of an {@code * IdentityHashMap} all are). * *

Note: The returned view performs slightly better when {@code set1} is the smaller of * the two sets. If you have reason to believe one of your sets will generally be smaller than the * other, pass it first. Unfortunately, since this method sets the generic type of the returned * set based on the type of the first set passed, this could in rare cases force you to make a * cast, for example: * *

{@code
     * Set aFewBadObjects = ...
     * Set manyBadStrings = ...
     *
     * // impossible for a non-String to be in the intersection
     * SuppressWarnings("unchecked")
     * Set badStrings = (Set) Sets.intersection(
     *     aFewBadObjects, manyBadStrings);
     * }
     *
     * 

This is unfortunate, but should come up only very rarely. * * @param * @param set1 * @param set2 * @return * @throws IllegalArgumentException * @see N#intersection(int[], int[]) * @see N#intersection(Collection, Collection) * @see N#commonSet(Collection, Collection) * @see Collection#retainAll(Collection) */ public static SetView intersection(final Set set1, final Set set2) throws IllegalArgumentException { // N.checkArgNotNull(set1, "set1"); // N.checkArgNotNull(set2, "set2"); Set tmp = null; if (N.isEmpty(set1) || N.isEmpty(set2)) { tmp = N.emptySet(); } else { tmp = new AbstractSet<>() { @Override public ObjIterator iterator() { return new ObjIterator<>() { private final Iterator iter1 = set1.iterator(); private final E NONE = (E) N.NULL_MASK; //NOSONAR private E next = NONE; private E tmp = null; @Override public boolean hasNext() { if (next != NONE) { return true; } while (iter1.hasNext()) { next = iter1.next(); if (set2.contains(next)) { return true; } } next = NONE; return false; } @Override public E next() { if (!hasNext()) { throw new NoSuchElementException(InternalUtil.ERROR_MSG_FOR_NO_SUCH_EX); } tmp = next; next = NONE; return tmp; } }; } @Override public boolean contains(final Object object) { return set1.contains(object) && set2.contains(object); } @Override public boolean containsAll(final Collection collection) { return set1.containsAll(collection) && set2.containsAll(collection); } @Override public int size() { int size = 0; for (final E e : set1) { if (set2.contains(e)) { size++; } } return size; } @Override public boolean isEmpty() { return Collections.disjoint(set1, set2); } }; } return new SetView<>(tmp) { }; } /** * Returns an unmodifiable view of the difference of two sets. The returned set contains * all elements that are contained by {@code set1} and not contained by {@code set2}. {@code set2} * May also contain elements not present in {@code set1}; these are simply ignored. The iteration * order of the returned set matches that of {@code set1}. * *

Results are undefined if {@code set1} and {@code set2} are sets based on different * equivalence relations (as {@code HashSet}, {@code TreeSet}, and the keySet of an {@code * IdentityHashMap} all are). * * @param * @param set1 * @param set2 * @return * @throws IllegalArgumentException * @see N#difference(Collection, Collection) * @see N#symmetricDifference(Collection, Collection) * @see N#excludeAll(Collection, Collection) * @see N#excludeAllToSet(Collection, Collection) * @see N#removeAll(Collection, Iterable) * @see N#intersection(Collection, Collection) * @see N#commonSet(Collection, Collection) * @see Difference#of(Collection, Collection) */ public static SetView difference(final Set set1, final Set set2) throws IllegalArgumentException { // N.checkArgNotNull(set1, "set1"); // N.checkArgNotNull(set2, "set2"); Set tmp = null; if (N.isEmpty(set1)) { tmp = N.emptySet(); } else if (N.isEmpty(set2)) { tmp = set1; } else { tmp = new AbstractSet<>() { @Override public ObjIterator iterator() { return new ObjIterator<>() { private final Iterator iter1 = set1.iterator(); private final E NONE = (E) N.NULL_MASK; //NOSONAR private E next = NONE; private E tmp = null; @Override public boolean hasNext() { if (next != NONE) { return true; } while (iter1.hasNext()) { next = iter1.next(); if (!set2.contains(next)) { return true; } } next = NONE; return false; } @Override public E next() { if (!hasNext()) { throw new NoSuchElementException(InternalUtil.ERROR_MSG_FOR_NO_SUCH_EX); } tmp = next; next = NONE; return tmp; } }; } @Override public boolean contains(final Object object) { return set1.contains(object) && !set2.contains(object); } @Override public int size() { int size = 0; for (final E e : set1) { if (!set2.contains(e)) { size++; } } return size; } @Override public boolean isEmpty() { //noinspection SuspiciousMethodCalls return set2.containsAll(set1); } }; } return new SetView<>(tmp) { }; } /** * Returns an unmodifiable view of the symmetric difference of two sets. The returned set * contains all elements that are contained in either {@code set1} or {@code set2} but not in * both. The iteration order of the returned set is undefined. * *

Results are undefined if {@code set1} and {@code set2} are sets based on different * equivalence relations (as {@code HashSet}, {@code TreeSet}, and the keySet of an {@code * IdentityHashMap} all are). * * @param * @param set1 * @param set2 * @return * @throws IllegalArgumentException */ public static SetView symmetricDifference(final Set set1, final Set set2) throws IllegalArgumentException { // N.checkArgNotNull(set1, "set1"); // N.checkArgNotNull(set2, "set2"); Set tmp = null; if (N.isEmpty(set1)) { tmp = N.isEmpty(set2) ? N.emptySet() : set2; } else if (N.isEmpty(set2)) { tmp = set1; } else { tmp = new AbstractSet<>() { @Override public ObjIterator iterator() { return new ObjIterator<>() { private final Iterator iter1 = set1.iterator(); private final Iterator iter2 = set2.iterator(); private final E NONE = (E) N.NULL_MASK; //NOSONAR private E next = NONE; private E tmp = null; @Override public boolean hasNext() { if (next != NONE) { return true; } while (iter1.hasNext()) { next = iter1.next(); if (!set2.contains(next)) { return true; } } while (iter2.hasNext()) { next = iter2.next(); if (!set1.contains(next)) { return true; } } next = NONE; return false; } @Override public E next() { if (!hasNext()) { throw new NoSuchElementException(InternalUtil.ERROR_MSG_FOR_NO_SUCH_EX); } tmp = next; next = NONE; return tmp; } }; } @Override public boolean contains(final Object object) { return set1.contains(object) ^ set2.contains(object); } @Override public int size() { int size = 0; for (final E e : set1) { if (!set2.contains(e)) { size++; } } for (final E e : set2) { if (!set1.contains(e)) { size++; } } return size; } @Override public boolean isEmpty() { return set1.equals(set2); } }; } return new SetView<>(tmp) { }; } /** * Returns a subset of the provided NavigableSet that falls within the specified range. * The subset includes all elements in the NavigableSet that are within the range defined by the lower and upper endpoints of the Range object. * The returned NavigableSet is a view of the original set, meaning changes in the returned set are reflected in the original set and vice versa. * The iteration order of the returned set matches that of the original set. * * @param the type of elements in the set, which must extend Comparable * @param set the original NavigableSet from which to derive the subset * @param range the Range object that defines the lower and upper bounds of the subset * @return a NavigableSet that includes all elements within the specified range * @throws IllegalArgumentException if the set is sorted by a non-natural ordering and the range endpoints are not mutually comparable */ public static > NavigableSet subSet(final NavigableSet set, final Range range) throws IllegalArgumentException { if (N.isEmpty(set)) { return N.emptyNavigableSet(); } if (set.comparator() != null && set.comparator() != N.NATURAL_COMPARATOR) { // NOSONAR N.checkArgument(set.comparator().compare(range.lowerEndpoint(), range.upperEndpoint()) <= 0, "set is using a custom comparator which is inconsistent with the natural ordering."); } return set.subSet(range.lowerEndpoint(), range.boundType() == BoundType.CLOSED_OPEN || range.boundType() == BoundType.CLOSED_CLOSED, range.upperEndpoint(), range.boundType() == BoundType.OPEN_CLOSED || range.boundType() == BoundType.CLOSED_CLOSED); } /** * * Note: copy from Google Guava under Apache License v2. *
* * Returns the set of all possible subsets of {@code set}. For example, * {@code powerSet(ImmutableSet.of(1, 2))} returns the set {@code {{}, * {1}, {2}, {1, 2}}}. * *

Elements appear in these subsets in the same iteration order as they * appeared in the input set. The order in which these subsets appear in the * outer set is undefined. Note that the power set of the empty set is not the * empty set, but an one-element set containing the empty set. * *

The returned set and its constituent sets use {@code equals} to decide * whether two elements are identical, even if the input set uses a different * concept of equivalence. * *

Performance notes: while the power set of a set with size {@code * n} is of size {@code 2^n}, its memory usage is only {@code O(n)}. When the * power set is constructed, the input set is merely copied. Only as the * power set is iterated are the individual subsets created, and these subsets * themselves occupy only a small constant amount of memory. * * @param * @param set the set of elements to construct a power set from * @return the sets of all possible subsets of {@code set} * @throws IllegalArgumentException if {@code set} has more than 30 unique * elements (causing the power set size to exceed the {@code int} range) * @see Power set article at * Wikipedia */ public static Set> powerSet(final Set set) { return new PowerSet<>(N.nullToEmpty(set)); } /** * Generates a rollup (a list of cumulative subsets) of the given collection. * Each subset is a list that includes the elements of the original collection from the start to a certain index. * The rollup starts with an empty list, and each subsequent list in the rollup includes one more element from the collection. * For example, given a collection [a, b, c], the rollup would be [[], [a], [a, b], [a, b, c]]. * * @param the type of elements in the collection * @param c the original collection from which to generate the rollup * @return a list of lists representing the rollup of the original collection */ public static List> rollup(final Collection c) { final List> res = new ArrayList<>(); res.add(new ArrayList<>()); if (N.notEmpty(c)) { for (final T e : c) { final List prev = res.get(res.size() - 1); final List cur = new ArrayList<>(prev.size() + 1); cur.addAll(prev); cur.add(e); res.add(cur); } } return res; } /** * Note: copy from Google Guava under Apache License v2. *
* * Returns a {@link Collection} of all the permutations of the specified * {@link Collection}. * *

Notes: This is an implementation of the Plain Changes algorithm * for permutation generation, described in Knuth's "The Art of Computer * Programming", Volume 4, Chapter 7, Section 7.2.1.2. * *

If the input list contains equal elements, some of the generated * permutations will be equal. * *

An empty collection has only one permutation, which is an empty list. * * @param * @param elements the original collection whose elements have to be permuted. * @return an immutable {@link Collection} containing all the different * permutations of the original collection. * @throws NullPointerException if the specified collection is {@code null} or has any * {@code null} elements. */ public static Collection> permutations(final Collection elements) { return new PermutationCollection<>(N.nullToEmpty(elements)); } /** * Note: copy from Google Guava under Apache License v2. *
* * Returns a {@link Collection} of all the permutations of the specified * {@link Iterable}. * *

Notes: This is an implementation of the algorithm for * Lexicographical Permutations Generation, described in Knuth's "The Art of * Computer Programming", Volume 4, Chapter 7, Section 7.2.1.2. The * iteration order follows the lexicographical order. This means that * the first permutation will be in ascending order, and the last will be in * descending order. * *

Duplicate elements are considered equal. For example, the list [1, 1] * will have only one permutation, instead of two. This is why the elements * have to implement {@link Comparable}. * *

An empty iterable has only one permutation, which is an empty list. * *

This method is equivalent to * {@code Collections2.orderedPermutations(list, Ordering.natural())}. * * @param * @param elements the original iterable whose elements have to be permuted. * @return an immutable {@link Collection} containing all the different * permutations of the original iterable. */ public static > Collection> orderedPermutations(final Collection elements) { return orderedPermutations(N.nullToEmpty(elements), N.NATURAL_COMPARATOR); } /** * Note: copy from Google Guava under Apache License v2. *
* * Returns a {@link Collection} of all the permutations of the specified * {@link Iterable} using the specified {@link Comparator} for establishing * the lexicographical ordering. * *

Examples:

   {@code
     *
     *   for (List perm : orderedPermutations(asList("b", "c", "a"))) {
     *     println(perm);
     *   }
     *   // -> ["a", "b", "c"]
     *   // -> ["a", "c", "b"]
     *   // -> ["b", "a", "c"]
     *   // -> ["b", "c", "a"]
     *   // -> ["c", "a", "b"]
     *   // -> ["c", "b", "a"]
     *
     *   for (List perm : orderedPermutations(asList(1, 2, 2, 1))) {
     *     println(perm);
     *   }
     *   // -> [1, 1, 2, 2]
     *   // -> [1, 2, 1, 2]
     *   // -> [1, 2, 2, 1]
     *   // -> [2, 1, 1, 2]
     *   // -> [2, 1, 2, 1]
     *   // -> [2, 2, 1, 1]}
* *

Notes: This is an implementation of the algorithm for * Lexicographical Permutations Generation, described in Knuth's "The Art of * Computer Programming", Volume 4, Chapter 7, Section 7.2.1.2. The * iteration order follows the lexicographical order. This means that * the first permutation will be in ascending order, and the last will be in * descending order. * *

Elements that compare equal are considered equal, and no new permutations * are created by swapping them. * *

An empty iterable has only one permutation, which is an empty list. * * @param * @param elements the original iterable whose elements have to be permuted. * @param comparator a comparator for the iterable's elements. * @return an immutable {@link Collection} containing all the different * permutations of the original iterable. */ public static Collection> orderedPermutations(final Collection elements, final Comparator comparator) { return new OrderedPermutationCollection<>(N.nullToEmpty(elements), comparator); } /** * Note: copy from Google Guava under Apache License v2. *
* * Returns every possible list that can be formed by choosing one element * from each of the given lists in order; the "n-ary * Cartesian * product" of the lists. For example:

   {@code
     *
     *   Lists.cartesianProduct(ImmutableList.of(
     *       ImmutableList.of(1, 2),
     *       ImmutableList.of("A", "B", "C")))}
* *

returns a list containing six lists in the following order: * *

    *
  • {@code ImmutableList.of(1, "A")} *
  • {@code ImmutableList.of(1, "B")} *
  • {@code ImmutableList.of(1, "C")} *
  • {@code ImmutableList.of(2, "A")} *
  • {@code ImmutableList.of(2, "B")} *
  • {@code ImmutableList.of(2, "C")} *
* *

The result is guaranteed to be in the "traditional", lexicographical * order for Cartesian products that you would get from nesting for loops: *

   {@code
     *
     *   for (B b0 : lists.get(0)) {
     *     for (B b1 : lists.get(1)) {
     *       ...
     *       ImmutableList tuple = ImmutableList.of(b0, b1, ...);
     *       // operate on tuple
     *     }
     *   }}
* *

Note that if any input list is empty, the Cartesian product will also be * empty. If no lists at all are provided (an empty list), the resulting * Cartesian product has one element, an empty list (counter-intuitive, but * mathematically consistent). * *

Performance notes: while the cartesian product of lists of size * {@code m, n, p} is a list of size {@code m x n x p}, its actual memory * consumption is much smaller. When the cartesian product is constructed, the * input lists are merely copied. Only as the resulting list is iterated are * the individual lists created, and these are not retained after iteration. * * @param any common base class shared by all axes (often just {@link * Object}) * @param cs the lists to choose elements from, in the order that * the elements chosen from those lists should appear in the resulting * lists * @return * lists * @throws IllegalArgumentException if the size of the cartesian product is greater than {@link Integer#MAX_VALUE} */ @SafeVarargs public static List> cartesianProduct(final Collection... cs) { return cartesianProduct(Array.asList(cs)); } /** * Note: copy from Google Guava under Apache License v2. *
* * Returns every possible list that can be formed by choosing one element * from each of the given lists in order; the "n-ary * Cartesian * product" of the lists. For example:

   {@code
     *
     *   Lists.cartesianProduct(ImmutableList.of(
     *       ImmutableList.of(1, 2),
     *       ImmutableList.of("A", "B", "C")))}
* *

returns a list containing six lists in the following order: * *

    *
  • {@code ImmutableList.of(1, "A")} *
  • {@code ImmutableList.of(1, "B")} *
  • {@code ImmutableList.of(1, "C")} *
  • {@code ImmutableList.of(2, "A")} *
  • {@code ImmutableList.of(2, "B")} *
  • {@code ImmutableList.of(2, "C")} *
* *

The result is guaranteed to be in the "traditional", lexicographical * order for Cartesian products that you would get from nesting for loops: *

   {@code
     *
     *   for (B b0 : lists.get(0)) {
     *     for (B b1 : lists.get(1)) {
     *       ...
     *       ImmutableList tuple = ImmutableList.of(b0, b1, ...);
     *       // operate on tuple
     *     }
     *   }}
* *

Note that if any input list is empty, the Cartesian product will also be * empty. If no lists at all are provided (an empty list), the resulting * Cartesian product has one element, an empty list (counter-intuitive, but * mathematically consistent). * *

Performance notes: while the cartesian product of lists of size * {@code m, n, p} is a list of size {@code m x n x p}, its actual memory * consumption is much smaller. When the cartesian product is constructed, the * input lists are merely copied. Only as the resulting list is iterated are * the individual lists created, and these are not retained after iteration. * * @param any common base class shared by all axes (often just {@link * Object}) * @param cs the lists to choose elements from, in the order that * the elements chosen from those lists should appear in the resulting * lists * @return * lists * @throws IllegalArgumentException if the size of the cartesian product is greater than {@link Integer#MAX_VALUE} */ public static List> cartesianProduct(final Collection> cs) { return new CartesianList<>(N.nullToEmpty(cs)); } /** * Returns {@code true} if the second list is a permutation of the first. * * @param a * @param b * @return {@code true}, if is permutations */ private static boolean isPermutations(final Collection a, final Collection b) { if (a.size() != b.size()) { return false; } return N.difference(a, b).size() == 0; } /** * The Class PowerSet. * * @param */ private static final class PowerSet extends AbstractSet> { /** The input set. */ final ImmutableMap inputSet; /** * Instantiates a new power set. * * @param input */ PowerSet(final Set input) { inputSet = indexMap(input); N.checkArgument(inputSet.size() <= 30, "Too many elements to create power set: %s > 30", inputSet.size()); } /** * * @return the int */ @Override public int size() { return 1 << inputSet.size(); } /** * Checks if is empty. * * @return {@code true}, if is empty */ @Override public boolean isEmpty() { return false; } /** * * @return the iterator */ @Override public Iterator> iterator() { return new Iterator<>() { private final int size = size(); private int position; @Override public boolean hasNext() { return position < size; } @Override public Set next() { if (!hasNext()) { throw new NoSuchElementException(InternalUtil.ERROR_MSG_FOR_NO_SUCH_EX); } return new SubSet<>(inputSet, position++); } @Override public void remove() { throw new UnsupportedOperationException(); } }; } /** * * @param obj * @return */ @Override public boolean contains(final Object obj) { if (obj instanceof final Set set) { //noinspection SuspiciousMethodCalls return inputSet.keySet().containsAll(set); } return false; } /** * * @param obj * @return */ @Override public boolean equals(final Object obj) { if (obj instanceof final PowerSet that) { return inputSet.equals(that.inputSet); } return super.equals(obj); } /** * * @return the int */ @Override public int hashCode() { /* * The sum of the sums of the hash codes in each subset is just the sum of * each input element's hash code times the number of sets that element * appears in. Each element appears in exactly half of the 2^n sets, so: */ return inputSet.keySet().hashCode() << (inputSet.size() - 1); } @Override public String toString() { return "powerSet(" + inputSet + ")"; } private static ImmutableMap indexMap(final Collection c) { final Map map = new LinkedHashMap<>(); int i = 0; for (final E e : c) { map.put(e, i++); } return ImmutableMap.wrap(map); } } /** * The Class SubSet. * * @param */ private static final class SubSet extends AbstractSet { //NOSONAR /** The input set. */ private final ImmutableMap inputSet; /** The elements. */ private final ImmutableList elements; /** The mask. */ private final int mask; /** * Instantiates a new subset. * * @param inputSet * @param mask */ SubSet(final ImmutableMap inputSet, final int mask) { this.inputSet = inputSet; elements = ImmutableList.copyOf(inputSet.keySet()); this.mask = mask; } /** * * @return the iterator */ @Override public Iterator iterator() { return new Iterator<>() { int remainingSetBits = mask; @Override public boolean hasNext() { return remainingSetBits != 0; } @Override public E next() { final int index = Integer.numberOfTrailingZeros(remainingSetBits); if (index == 32) { throw new NoSuchElementException(InternalUtil.ERROR_MSG_FOR_NO_SUCH_EX); } remainingSetBits &= ~(1 << index); return elements.get(index); } @Override public void remove() { throw new UnsupportedOperationException(); } }; } /** * * @return the int */ @Override public int size() { return Integer.bitCount(mask); } /** * * @param o * @return */ @Override public boolean contains(final Object o) { @SuppressWarnings("SuspiciousMethodCalls") final Integer index = inputSet.get(o); return index != null && (mask & (1 << index)) != 0; } } /** * The Class PermutationCollection. * * @param */ private static final class PermutationCollection extends AbstractCollection> { /** The input list. */ final List inputList; /** * Instantiates a new permutation collection. * * @param input */ PermutationCollection(final Collection input) { inputList = new ArrayList<>(input); } /** * * @return the int */ @Override public int size() { return Numbers.factorial(inputList.size()); } /** * Checks if is empty. * * @return {@code true}, if is empty */ @Override public boolean isEmpty() { return false; } /** * * @return the iterator */ @Override public Iterator> iterator() { return PermutationIterator.of(inputList); } /** * * @param obj * @return */ @Override public boolean contains(final Object obj) { if (obj instanceof Collection) { return isPermutations(inputList, (Collection) obj); } return false; } /** * * @return the string */ @Override public String toString() { return "permutations(" + inputList + ")"; } } /** * The Class OrderedPermutationCollection. * * @param */ private static final class OrderedPermutationCollection extends AbstractCollection> { /** The input list. */ final List inputList; /** The comparator. */ final Comparator comparator; /** The size. */ final int size; /** * Instantiates a new ordered permutation collection. * * @param input * @param comparator */ OrderedPermutationCollection(final Collection input, final Comparator comparator) { inputList = new ArrayList<>(input); N.sort(inputList, comparator); this.comparator = comparator; size = calculateSize(inputList, comparator); } /** * * @return the int */ @Override public int size() { return size; } /** * Checks if is empty. * * @return {@code true}, if is empty */ @Override public boolean isEmpty() { return false; } /** * * @return the iterator */ @Override public Iterator> iterator() { return PermutationIterator.ordered(inputList, comparator); } /** * * @param obj * @return */ @Override public boolean contains(final Object obj) { if (obj instanceof Collection) { return isPermutations(inputList, (Collection) obj); } return false; } /** * * @return the string */ @Override public String toString() { return "orderedPermutationCollection(" + inputList + ")"; } /** * The number of permutations with repeated elements is calculated as * follows: *

    *
  • For an empty list, it is 1 (base case).
  • *
  • When r numbers are added to a list of n-r elements, the number of * permutations is increased by a factor of (n choose r).
  • *
* * @param * @param sortedInputList * @param comparator * @return the int */ private static int calculateSize(final List sortedInputList, final Comparator comparator) { long permutations = 1; int n = 1; int r = 1; while (n < sortedInputList.size()) { final int comparison = comparator.compare(sortedInputList.get(n - 1), sortedInputList.get(n)); if (comparison < 0) { // We move to the next non-repeated element. permutations *= Numbers.binomial(n, r); r = 0; if (!isPositiveInt(permutations)) { return Integer.MAX_VALUE; } } n++; r++; } permutations *= Numbers.binomial(n, r); if (!isPositiveInt(permutations)) { return Integer.MAX_VALUE; } return (int) permutations; } /** * Checks if is positive int. * * @param n * @return {@code true}, if is positive int */ private static boolean isPositiveInt(final long n) { return n >= 0 && n <= Integer.MAX_VALUE; } } /** * The Class CartesianList. * * @param */ private static final class CartesianList extends AbstractList> implements RandomAccess { //NOSONAR /** The axes. */ private final transient Object[][] axes; //NOSONAR /** The axes size product. */ private final transient int[] axesSizeProduct; //NOSONAR /** * Instantiates a new cartesian list. * * @param cs */ CartesianList(final Collection> cs) { final Iterator> iter = cs.iterator(); axes = new Object[cs.size()][]; for (int i = 0, len = axes.length; i < len; i++) { axes[i] = iter.next().toArray(); } axesSizeProduct = new int[axes.length + 1]; axesSizeProduct[axes.length] = 1; try { for (int i = axes.length - 1; i >= 0; i--) { axesSizeProduct[i] = Numbers.multiplyExact(axesSizeProduct[i + 1], axes[i].length); } } catch (final ArithmeticException e) { throw new IllegalArgumentException("Cartesian product too large; must have size at most Integer.MAX_VALUE"); } } /** * * @param index * @return the list */ @Override public List get(final int index) throws IllegalArgumentException { N.checkArgument(index < size(), "Invalid index %s. It must be less than the size %s", index, size()); final List result = new ArrayList<>(axes.length); for (int k = 0, len = axes.length; k < len; k++) { result.add((E) axes[k][getAxisIndexForProductIndex(index, k)]); } return result; } /** * * @return the int */ @Override public int size() { return axesSizeProduct[0]; } /** * * @param obj * @return */ @Override public boolean contains(final Object obj) { if (!(obj instanceof final Collection c) || (c.size() != axes.length)) { return false; } int idx = 0; for (final Object e : c) { boolean found = false; for (final Object p : axes[idx++]) { if (N.equals(e, p)) { found = true; break; } } if (!found) { return false; } } return true; } /** * Gets the axis index for product index. * * @param index * @param axis * @return the axis index for product index */ private int getAxisIndexForProductIndex(final int index, final int axis) { return (index / axesSizeProduct[axis + 1]) % axes[axis].length; } } /** * The Class Slice. * * @param */ @SuppressFBWarnings("EQ_DOESNT_OVERRIDE_EQUALS") static final class Slice extends ImmutableCollection { //NOSONAR /** The start index. */ private final int fromIndex; /** The to index. */ private final int toIndex; /** * Instantiates a new subcollection. * * @param a * @param fromIndex * @param toIndex */ Slice(final T[] a, final int fromIndex, final int toIndex) { this(Array.asList(a), fromIndex, toIndex); } /** * Instantiates a new subcollection. * * @param c * @param fromIndex * @param toIndex */ Slice(final List c, final int fromIndex, final int toIndex) { super(fromIndex == 0 && toIndex == c.size() ? c : c.subList(fromIndex, toIndex)); this.fromIndex = 0; this.toIndex = toIndex - fromIndex; } /** * Instantiates a new subcollection. * * @param c * @param fromIndex * @param toIndex */ Slice(final Collection c, final int fromIndex, final int toIndex) { super(c instanceof List ? ((List) c).subList(fromIndex, toIndex) : c); this.fromIndex = c instanceof List ? 0 : fromIndex; this.toIndex = c instanceof List ? toIndex - fromIndex : toIndex; } /** * * @param o * @return */ @Override public boolean contains(final Object o) { for (final T element : this) { if (N.equals(element, o)) { return true; } } return false; } /** * * @param c * @return */ @Override public boolean containsAll(final Collection c) { for (final Object e : c) { if (!contains(e)) { return false; } } return true; } /** * Checks if is empty. * * @return {@code true}, if is empty */ @Override public boolean isEmpty() { return size() == 0; } /** * * @return the int */ @Override public int size() { return toIndex - fromIndex; //NOSONAR } /** * * @return the iterator */ @Override public ObjIterator iterator() { if (coll == null || fromIndex == toIndex) { return ObjIterator.empty(); } final Iterator iter = coll.iterator(); if (fromIndex == 0 && toIndex == coll.size()) { return ObjIterator.of(iter); } else if (fromIndex == 0) { return Iterators.limit(iter, toIndex - fromIndex); //NOSONAR } else if (toIndex == coll.size()) { return Iterators.skip(iter, fromIndex); } else { return Iterators.skipAndLimit(iter, fromIndex, toIndex - fromIndex); //NOSONAR } } /** * * @return the object[] */ @Override public Object[] toArray() { final Iterator iter = this.iterator(); final Object[] a = new Object[size()]; for (int i = 0, len = a.length; i < len; i++) { a[i] = iter.next(); } return a; } /** * * @param * @param a * @return the a[] */ @Override public A[] toArray(A[] a) { if (a.length < size()) { a = N.copyOf(a, size()); } final Iterator iter = this.iterator(); for (int i = 0, len = a.length; i < len; i++) { a[i] = (A) iter.next(); } return a; } } /** * Checks if the specified {@code arg} is {@code null} or empty, and throws {@code IllegalArgumentException} if it is. * * @param * @param arg * @param argNameOrErrorMsg * @return * @throws IllegalArgumentException if the specified {@code arg} is {@code null} or empty. */ static Iterator iterateNonEmpty(final Iterable arg, final String argNameOrErrorMsg) { final Iterator iter = arg == null ? ObjIterator.empty() : arg.iterator(); final boolean isNullOrEmpty = arg == null || (arg instanceof Collection ? ((Collection) arg).size() == 0 : !iter.hasNext()); if (isNullOrEmpty) { if (argNameOrErrorMsg.indexOf(' ') == N.INDEX_NOT_FOUND) { throw new IllegalArgumentException("'" + argNameOrErrorMsg + "' cannot be null or empty"); } else { throw new IllegalArgumentException(argNameOrErrorMsg); } } return iter; } }