com.landawn.abacus.util.Iterables Maven / Gradle / Ivy
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.landawn.abacus.util;
import java.util.AbstractSet;
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.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.TreeSet;
import com.landawn.abacus.util.u.Nullable;
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;
import com.landawn.abacus.util.function.Function;
/**
*
* 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.
*
*
*
* This is a utility class for iterable data structures, including {@code Collection/Array/Iterator}.
*
*
*
* The methods in this class should only read the input {@code Collection/Array/Iterator} parameters, not modify them.
*
*
*/
public final class Iterables {
Iterables() {
// Utility class.
}
@SafeVarargs
public static OptionalChar min(final char... a) {
return a == null || a.length == 0 ? OptionalChar.empty() : OptionalChar.of(N.min(a));
}
@SafeVarargs
public static OptionalByte min(final byte... a) {
return a == null || a.length == 0 ? OptionalByte.empty() : OptionalByte.of(N.min(a));
}
@SafeVarargs
public static OptionalShort min(final short... a) {
return a == null || a.length == 0 ? OptionalShort.empty() : OptionalShort.of(N.min(a));
}
@SafeVarargs
public static OptionalInt min(final int... a) {
return a == null || a.length == 0 ? OptionalInt.empty() : OptionalInt.of(N.min(a));
}
@SafeVarargs
public static OptionalLong min(final long... a) {
return a == null || a.length == 0 ? OptionalLong.empty() : OptionalLong.of(N.min(a));
}
@SafeVarargs
public static OptionalFloat min(final float... a) {
return a == null || a.length == 0 ? OptionalFloat.empty() : OptionalFloat.of(N.min(a));
}
@SafeVarargs
public static OptionalDouble min(final double... a) {
return a == null || a.length == 0 ? OptionalDouble.empty() : OptionalDouble.of(N.min(a));
}
@SafeVarargs
public static OptionalChar max(final char... a) {
return a == null || a.length == 0 ? OptionalChar.empty() : OptionalChar.of(N.max(a));
}
@SafeVarargs
public static OptionalByte max(final byte... a) {
return a == null || a.length == 0 ? OptionalByte.empty() : OptionalByte.of(N.max(a));
}
@SafeVarargs
public static OptionalShort max(final short... a) {
return a == null || a.length == 0 ? OptionalShort.empty() : OptionalShort.of(N.max(a));
}
@SafeVarargs
public static OptionalInt max(final int... a) {
return a == null || a.length == 0 ? OptionalInt.empty() : OptionalInt.of(N.max(a));
}
@SafeVarargs
public static OptionalLong max(final long... a) {
return a == null || a.length == 0 ? OptionalLong.empty() : OptionalLong.of(N.max(a));
}
@SafeVarargs
public static OptionalFloat max(final float... a) {
return a == null || a.length == 0 ? OptionalFloat.empty() : OptionalFloat.of(N.max(a));
}
@SafeVarargs
public static OptionalDouble max(final double... a) {
return a == null || a.length == 0 ? OptionalDouble.empty() : OptionalDouble.of(N.max(a));
}
public static > Nullable min(final T[] a) {
return N.isNullOrEmpty(a) ? Nullable. empty() : Nullable.of(N.min(a));
}
public static Nullable min(final T[] a, final Comparator super T> cmp) {
return N.isNullOrEmpty(a) ? Nullable. empty() : Nullable.of(N.min(a, cmp));
}
public static > Nullable min(final Collection extends T> c) {
return N.isNullOrEmpty(c) ? Nullable. empty() : Nullable.of(N.min(c));
}
public static Nullable min(final Collection extends T> c, final Comparator super T> cmp) {
return N.isNullOrEmpty(c) ? Nullable. empty() : Nullable.of(N.min(c, cmp));
}
public static > Nullable min(final Iterator extends T> iter) {
return min(iter, N.NULL_MAX_COMPARATOR);
}
public static Nullable min(final Iterator extends T> iter, Comparator super T> cmp) {
cmp = cmp == null ? N.NULL_MAX_COMPARATOR : cmp;
if (iter == null || iter.hasNext() == false) {
return Nullable. empty();
}
T candidate = null;
T next = null;
do {
next = iter.next();
if (next == null && cmp == N.NULL_MIN_COMPARATOR) {
return Nullable.of(next);
} else if (cmp.compare(next, candidate) < 0) {
candidate = next;
}
} while (iter.hasNext());
return Nullable.of(candidate);
}
@SuppressWarnings("rawtypes")
public static Nullable minBy(final T[] a, final Function super T, ? extends Comparable> keyMapper) {
return min(a, Fn.comparingBy(keyMapper));
}
@SuppressWarnings("rawtypes")
public static Nullable minBy(final Collection extends T> c, final Function super T, ? extends Comparable> keyMapper) {
return min(c, Fn.comparingBy(keyMapper));
}
@SuppressWarnings("rawtypes")
public static Nullable minBy(final Iterator extends T> iter, final Function super T, ? extends Comparable> keyMapper) {
return min(iter, Fn.comparingBy(keyMapper));
}
public static > Nullable max(final T[] a) {
return N.isNullOrEmpty(a) ? Nullable. empty() : Nullable.of(N.max(a));
}
public static Nullable max(final T[] a, final Comparator super T> cmp) {
return N.isNullOrEmpty(a) ? Nullable. empty() : Nullable.of(N.max(a, cmp));
}
public static > Nullable max(final Collection extends T> c) {
return N.isNullOrEmpty(c) ? Nullable. empty() : Nullable.of(N.max(c));
}
public static Nullable max(final Collection extends T> c, final Comparator super T> cmp) {
return N.isNullOrEmpty(c) ? Nullable. empty() : Nullable.of(N.max(c, cmp));
}
public static > Nullable max(final Iterator extends T> iter) {
return max(iter, N.NULL_MIN_COMPARATOR);
}
public static Nullable max(final Iterator extends T> iter, Comparator super T> cmp) {
cmp = cmp == null ? N.NULL_MIN_COMPARATOR : cmp;
if (iter == null || iter.hasNext() == false) {
return Nullable. empty();
}
T candidate = null;
T next = null;
do {
next = iter.next();
if (next == null && cmp == N.NULL_MAX_COMPARATOR) {
return Nullable.of(next);
} else if (cmp.compare(next, candidate) > 0) {
candidate = next;
}
} while (iter.hasNext());
return Nullable.of(candidate);
}
@SuppressWarnings("rawtypes")
public static Nullable maxBy(final T[] a, final Function super T, ? extends Comparable> keyMapper) {
return max(a, Fn.comparingBy(keyMapper));
}
@SuppressWarnings("rawtypes")
public static Nullable maxBy(final Collection extends T> c, final Function super T, ? extends Comparable> keyMapper) {
return max(c, Fn.comparingBy(keyMapper));
}
@SuppressWarnings("rawtypes")
public static Nullable maxBy(final Iterator extends T> iter, final Function super T, ? extends Comparable> keyMapper) {
return max(iter, Fn.comparingBy(keyMapper));
}
public static > Nullable median(final T[] a) {
return N.isNullOrEmpty(a) ? Nullable. empty() : Nullable.of(N.median(a));
}
public static > Nullable median(final Collection extends T> c) {
return N.isNullOrEmpty(c) ? Nullable. empty() : Nullable.of(N.median(c));
}
public static Nullable median(final T[] a, final Comparator super T> cmp) {
return N.isNullOrEmpty(a) ? Nullable. empty() : Nullable.of(N.median(a, cmp));
}
public static Nullable median(final Collection extends T> c, final Comparator super T> cmp) {
return N.isNullOrEmpty(c) ? Nullable. empty() : Nullable.of(N.median(c, cmp));
}
@SuppressWarnings("rawtypes")
public static Nullable medianBy(final T[] a, final Function super T, ? extends Comparable> keyMapper) {
return median(a, Fn.comparingBy(keyMapper));
}
@SuppressWarnings("rawtypes")
public static Nullable medianBy(final Collection extends T> c, final Function super T, ? extends Comparable> keyMapper) {
return median(c, Fn.comparingBy(keyMapper));
}
public static > Nullable kthLargest(final Collection extends T> c, final int k) {
return N.isNullOrEmpty(c) ? Nullable. empty() : Nullable.of(N.kthLargest(c, k));
}
public static > Nullable kthLargest(final T[] a, final int k) {
return N.isNullOrEmpty(a) ? Nullable. empty() : Nullable.of(N.kthLargest(a, k));
}
public static Nullable kthLargest(final Collection extends T> c, final int k, final Comparator super T> cmp) {
return N.isNullOrEmpty(c) ? Nullable. empty() : Nullable.of(N.kthLargest(c, k, cmp));
}
public static Nullable kthLargest(final T[] a, final int k, final Comparator super T> cmp) {
return N.isNullOrEmpty(a) ? Nullable. empty() : Nullable.of(N.kthLargest(a, k, cmp));
}
public static OptionalInt indexOf(final Collection> c, final Object objToFind) {
return Index.of(c, objToFind);
}
public static OptionalInt indexOf(final Object[] a, final Object objToFind) {
return Index.of(a, objToFind);
}
public static OptionalInt lastIndexOf(final Collection> c, final Object objToFind) {
return Index.last(c, objToFind);
}
public static OptionalInt lastIndexOf(final Object[] a, final Object objToFind) {
return Index.last(a, objToFind);
}
public static OptionalInt findFirstOrLastIndex(final Collection extends T> c,
final Throwables.Predicate super T, E> predicateForFirst, final Throwables.Predicate super T, E2> predicateForLast) throws E, E2 {
if (N.isNullOrEmpty(c)) {
return OptionalInt.empty();
}
final OptionalInt res = N.findFirstIndex(c, predicateForFirst);
return res.isPresent() ? res : N.findLastIndex(c, predicateForLast);
}
/**
* Find first or last index.
*
* @param the generic type
* @param the element type
* @param the generic type
* @param a the a
* @param predicateForFirst the predicate for first
* @param predicateForLast the predicate for last
* @return the optional int
* @throws E the e
* @throws E2 the e2
*/
public static OptionalInt findFirstOrLastIndex(final T[] a,
final Throwables.Predicate super T, E> predicateForFirst, final Throwables.Predicate super T, E2> predicateForLast) throws E, E2 {
if (N.isNullOrEmpty(a)) {
return OptionalInt.empty();
}
final OptionalInt res = N.findFirstIndex(a, predicateForFirst);
return res.isPresent() ? res : N.findLastIndex(a, predicateForLast);
}
/**
* Find first and last index.
*
* @param the generic type
* @param the element type
* @param c the c
* @param predicate the predicate
* @return the pair
* @throws E the e
*/
public static Pair findFirstAndLastIndex(final Collection extends T> c,
final Throwables.Predicate super T, E> predicate) throws E {
return findFirstAndLastIndex(c, predicate, predicate);
}
/**
* Find first and last index.
*
* @param the generic type
* @param the element type
* @param the generic type
* @param c the c
* @param predicateForFirst the predicate for first
* @param predicateForLast the predicate for last
* @return the pair
* @throws E the e
* @throws E2 the e2
*/
public static Pair findFirstAndLastIndex(final Collection extends T> c,
final Throwables.Predicate super T, E> predicateForFirst, final Throwables.Predicate super T, E2> predicateForLast) throws E, E2 {
if (N.isNullOrEmpty(c)) {
return Pair.of(OptionalInt.empty(), OptionalInt.empty());
}
return Pair.of(N.findFirstIndex(c, predicateForFirst), N.findLastIndex(c, predicateForLast));
}
/**
* Find first and last index.
*
* @param the generic type
* @param the element type
* @param a the a
* @param predicate the predicate
* @return the pair
* @throws E the e
*/
public static Pair findFirstAndLastIndex(final T[] a, final Throwables.Predicate super T, E> predicate)
throws E {
return findFirstAndLastIndex(a, predicate, predicate);
}
/**
* Find first and last index.
*
* @param the generic type
* @param the element type
* @param the generic type
* @param a the a
* @param predicateForFirst the predicate for first
* @param predicateForLast the predicate for last
* @return the pair
* @throws E the e
* @throws E2 the e2
*/
public static Pair findFirstAndLastIndex(final T[] a,
final Throwables.Predicate super T, E> predicateForFirst, final Throwables.Predicate super T, E2> predicateForLast) throws E, E2 {
if (N.isNullOrEmpty(a)) {
return Pair.of(OptionalInt.empty(), OptionalInt.empty());
}
return Pair.of(N.findFirstIndex(a, predicateForFirst), N.findLastIndex(a, predicateForLast));
}
/**
* Find first or last.
*
* @param the generic type
* @param the element type
* @param the generic type
* @param c the c
* @param predicateForFirst the predicate for first
* @param predicateForLast the predicate for last
* @return the nullable
* @throws E the e
* @throws E2 the e2
*/
public static Nullable findFirstOrLast(final Collection extends T> c,
final Throwables.Predicate super T, E> predicateForFirst, final Throwables.Predicate super T, E2> predicateForLast) throws E, E2 {
if (N.isNullOrEmpty(c)) {
return Nullable. empty();
}
final Nullable res = N.findFirst(c, predicateForFirst);
return res.isPresent() ? res : N.findLast(c, predicateForLast);
}
/**
* Find first or last.
*
* @param the generic type
* @param the element type
* @param the generic type
* @param a the a
* @param predicateForFirst the predicate for first
* @param predicateForLast the predicate for last
* @return the nullable
* @throws E the e
* @throws E2 the e2
*/
public static Nullable findFirstOrLast(final T[] a,
final Throwables.Predicate super T, E> predicateForFirst, final Throwables.Predicate super T, E2> predicateForLast) throws E, E2 {
if (N.isNullOrEmpty(a)) {
return Nullable. empty();
}
final Nullable res = N.findFirst(a, predicateForFirst);
return res.isPresent() ? res : N.findLast(a, predicateForLast);
}
/**
* Find first and last.
*
* @param the generic type
* @param the element type
* @param c the c
* @param predicate the predicate
* @return the pair
* @throws E the e
*/
public static Pair, Nullable> findFirstAndLast(final Collection extends T> c,
final Throwables.Predicate super T, E> predicate) throws E {
return findFirstAndLast(c, predicate, predicate);
}
/**
* Find first and last.
*
* @param the generic type
* @param the element type
* @param the generic type
* @param c the c
* @param predicateForFirst the predicate for first
* @param predicateForLast the predicate for last
* @return the pair
* @throws E the e
* @throws E2 the e2
*/
public static Pair, Nullable> findFirstAndLast(final Collection extends T> c,
final Throwables.Predicate super T, E> predicateForFirst, final Throwables.Predicate super T, E2> predicateForLast) throws E, E2 {
if (N.isNullOrEmpty(c)) {
return Pair.of(Nullable. empty(), Nullable. empty());
}
return Pair.of(N.findFirst(c, predicateForFirst), N.findLast(c, predicateForLast));
}
/**
* Find first and last.
*
* @param the generic type
* @param the element type
* @param a the a
* @param predicate the predicate
* @return the pair
* @throws E the e
*/
public static Pair, Nullable> findFirstAndLast(final T[] a, final Throwables.Predicate super T, E> predicate)
throws E {
return findFirstAndLast(a, predicate, predicate);
}
/**
* Find first and last.
*
* @param the generic type
* @param the element type
* @param the generic type
* @param a the a
* @param predicateForFirst the predicate for first
* @param predicateForLast the predicate for last
* @return the pair
* @throws E the e
* @throws E2 the e2
*/
public static Pair, Nullable> findFirstAndLast(final T[] a,
final Throwables.Predicate super T, E> predicateForFirst, final Throwables.Predicate super T, E2> predicateForLast) throws E, E2 {
if (N.isNullOrEmpty(a)) {
return Pair.of(Nullable. empty(), Nullable. empty());
}
return Pair.of(N.findFirst(a, predicateForFirst), N.findLast(a, predicateForLast));
}
// /**
// *
// * @param
// * @param
// * @param a
// * @param b
// * @return
// * @see N#crossJoin(Collection, Collection)
// * @deprecated replaced by {@code N.crossJoin(Collection, Collection)}
// */
// @Deprecated
// public static List> crossJoin(final Collection a, final Collection b) {
// return crossJoin(a, b, Fn. pair());
// }
//
// /**
// *
// * @param
// * @param
// * @param
// * @param
// * @param a
// * @param b
// * @param func
// * @return
// * @throws E
// * @see N#crossJoin(Collection, Collection, com.landawn.abacus.util.Throwables.BiFunction)
// * @deprecated replaced by {@code N.crossJoin(Collection, Collection, com.landawn.abacus.util.Try.BiFunction)}
// */
// @Deprecated
// public static List crossJoin(final Collection a, final Collection b,
// final Throwables.BiFunction super T, ? super U, R, E> func) throws E {
// N.checkArgNotNull(func, "func");
//
// final List result = new ArrayList<>(N.size(a) * N.size(b));
//
// if (N.isNullOrEmpty(a) || N.isNullOrEmpty(b)) {
// return result;
// }
//
// for (T ae : a) {
// for (U be : b) {
// result.add(func.apply(ae, be));
// }
// }
//
// return result;
// }
//
// /**
// * The time complexity is O(n + m) : n is the size of this Seq
and m is the size of specified collection b
.
// *
// * @param the generic type
// * @param the generic type
// * @param the element type
// * @param the generic type
// * @param a the a
// * @param b the b
// * @param leftKeyMapper the left key mapper
// * @param rightKeyMapper the right key mapper
// * @return the list
// * @throws E the e
// * @throws E2 the e2
// * @see N#innerJoin(Collection, Collection, com.landawn.abacus.util.Throwables.Function, com.landawn.abacus.util.Throwables.Function)
// * @see sql join
// * @deprecated replaced by {@code N.innerJoin(Collection, Collection, com.landawn.abacus.util.Try.Function, com.landawn.abacus.util.Try.Function)}
// */
// @Deprecated
// public static List> innerJoin(final Collection a, final Collection b,
// final Throwables.Function super T, ? extends K, E> leftKeyMapper, final Throwables.Function super U, ? extends K, E2> rightKeyMapper)
// throws E, E2 {
// final List> result = new ArrayList<>(N.min(9, N.size(a), N.size(b)));
//
// if (N.isNullOrEmpty(a) || N.isNullOrEmpty(b)) {
// return result;
// }
//
// final ListMultimap rightKeyMap = ListMultimap.from(b, rightKeyMapper);
//
// for (T left : a) {
// final List rights = rightKeyMap.get(leftKeyMapper.apply(left));
//
// if (N.notNullOrEmpty(rights)) {
// for (U right : rights) {
// result.add(Pair.of(left, right));
// }
// }
// }
//
// return result;
// }
//
// /**
// * The time complexity is O(n * m) : n is the size of this Seq
and m is the size of specified collection b
.
// *
// * @param the generic type
// * @param the generic type
// * @param the element type
// * @param a the a
// * @param b the b
// * @param predicate the predicate
// * @return the list
// * @throws E the e
// * @see N#innerJoin(Collection, Collection, com.landawn.abacus.util.Throwables.BiPredicate)
// * @see sql join
// * @deprecated replaced by {@code N.innerJoin(Collection, Collection, com.landawn.abacus.util.Try.BiPredicate)}
// */
// @Deprecated
// public static List> innerJoin(final Collection a, final Collection b,
// final Throwables.BiPredicate super T, ? super U, E> predicate) throws E {
// final List> result = new ArrayList<>(N.min(9, N.size(a), N.size(b)));
//
// if (N.isNullOrEmpty(a) || N.isNullOrEmpty(b)) {
// return result;
// }
//
// for (T left : a) {
// for (U right : b) {
// if (predicate.test(left, right)) {
// result.add(Pair.of(left, right));
// }
// }
// }
//
// return result;
// }
//
// /**
// * The time complexity is O(n + m) : n is the size of this Seq
and m is the size of specified collection b
.
// *
// * @param the generic type
// * @param the generic type
// * @param the element type
// * @param the generic type
// * @param a the a
// * @param b the b
// * @param leftKeyMapper the left key mapper
// * @param rightKeyMapper the right key mapper
// * @return the list
// * @throws E the e
// * @throws E2 the e2
// * @see N#fullJoin(Collection, Collection, com.landawn.abacus.util.Throwables.Function, com.landawn.abacus.util.Throwables.Function)
// * @see sql join
// * @deprecated replaced by {@code N.fullJoin(Collection, Collection, com.landawn.abacus.util.Try.Function, com.landawn.abacus.util.Try.Function)}
// */
// @Deprecated
// public static List> fullJoin(final Collection a, final Collection b,
// final Throwables.Function super T, ? extends K, E> leftKeyMapper, final Throwables.Function super U, ? extends K, E2> rightKeyMapper)
// throws E, E2 {
// final List> result = new ArrayList<>(N.max(9, N.size(a), N.size(b)));
//
// if (N.isNullOrEmpty(a)) {
// for (T left : a) {
// result.add(Pair.of(left, (U) null));
// }
// } else if (N.isNullOrEmpty(b)) {
// for (U right : b) {
// result.add(Pair.of((T) null, right));
// }
// } else {
// final ListMultimap rightKeyMap = ListMultimap.from(b, rightKeyMapper);
// final Map joinedRights = new IdentityHashMap<>();
//
// for (T left : a) {
// final List rights = rightKeyMap.get(leftKeyMapper.apply(left));
//
// if (N.notNullOrEmpty(rights)) {
// for (U right : rights) {
// result.add(Pair.of(left, right));
// joinedRights.put(right, right);
// }
// } else {
// result.add(Pair.of(left, (U) null));
// }
// }
//
// for (U right : b) {
// if (joinedRights.containsKey(right) == false) {
// result.add(Pair.of((T) null, right));
// }
// }
// }
//
// return result;
// }
//
// /**
// * The time complexity is O(n * m) : n is the size of this Seq
and m is the size of specified collection b
.
// *
// * @param the generic type
// * @param the generic type
// * @param the element type
// * @param a the a
// * @param b the b
// * @param predicate the predicate
// * @return the list
// * @throws E the e
// * @see N#fullJoin(Collection, Collection, com.landawn.abacus.util.Throwables.BiPredicate)
// * @see sql join
// * @deprecated replaced by {@code N.fullJoin(Collection, Collection, com.landawn.abacus.util.Try.BiPredicate)}
// */
// @Deprecated
// public static List> fullJoin(final Collection a, final Collection b,
// final Throwables.BiPredicate super T, ? super U, E> predicate) throws E {
// final List> result = new ArrayList<>(N.max(9, N.size(a), N.size(b)));
//
// if (N.isNullOrEmpty(a)) {
// for (T left : a) {
// result.add(Pair.of(left, (U) null));
// }
// } else if (N.isNullOrEmpty(b)) {
// for (U right : b) {
// result.add(Pair.of((T) null, right));
// }
// } else {
// final Map joinedRights = new IdentityHashMap<>();
//
// for (T left : a) {
// boolean joined = false;
//
// for (U right : b) {
// if (predicate.test(left, right)) {
// result.add(Pair.of(left, right));
// joinedRights.put(right, right);
// joined = true;
// }
// }
//
// if (joined == false) {
// result.add(Pair.of(left, (U) null));
// }
// }
//
// for (U right : b) {
// if (joinedRights.containsKey(right) == false) {
// result.add(Pair.of((T) null, right));
// }
// }
// }
//
// return result;
// }
//
// /**
// * The time complexity is O(n + m) : n is the size of this Seq
and m is the size of specified collection b
.
// *
// * @param the generic type
// * @param the generic type
// * @param the element type
// * @param the generic type
// * @param a the a
// * @param b the b
// * @param leftKeyMapper the left key mapper
// * @param rightKeyMapper the right key mapper
// * @return the list
// * @throws E the e
// * @throws E2 the e2
// * @see N#leftJoin(Collection, Collection, com.landawn.abacus.util.Throwables.Function, com.landawn.abacus.util.Throwables.Function)
// * @see sql join
// * @deprecated replaced by {@code N.leftJoin(Collection, Collection, com.landawn.abacus.util.Try.Function, com.landawn.abacus.util.Try.Function)}
// */
// @Deprecated
// public static List> leftJoin(final Collection a, final Collection b,
// final Throwables.Function super T, ? extends K, E> leftKeyMapper, final Throwables.Function super U, ? extends K, E2> rightKeyMapper)
// throws E, E2 {
// final List> result = new ArrayList<>(N.size(a));
//
// if (N.isNullOrEmpty(a)) {
// return result;
// } else if (N.isNullOrEmpty(b)) {
// for (T left : a) {
// result.add(Pair.of(left, (U) null));
// }
// } else {
// final ListMultimap rightKeyMap = ListMultimap.from(b, rightKeyMapper);
//
// for (T left : a) {
// final List rights = rightKeyMap.get(leftKeyMapper.apply(left));
//
// if (N.notNullOrEmpty(rights)) {
// for (U right : rights) {
// result.add(Pair.of(left, right));
// }
// } else {
// result.add(Pair.of(left, (U) null));
// }
// }
// }
//
// return result;
// }
//
// /**
// * The time complexity is O(n * m) : n is the size of this Seq
and m is the size of specified collection b
.
// *
// * @param the generic type
// * @param the generic type
// * @param the element type
// * @param a the a
// * @param b the b
// * @param predicate the predicate
// * @return the list
// * @throws E the e
// * @see N#leftJoin(Collection, Collection, com.landawn.abacus.util.Throwables.BiPredicate)
// * @see sql join
// * @deprecated replaced by {@code N.leftJoin(Collection, Collection, com.landawn.abacus.util.Try.BiPredicate)}
// */
// @Deprecated
// public static List> leftJoin(final Collection a, final Collection b,
// final Throwables.BiPredicate super T, ? super U, E> predicate) throws E {
// final List> result = new ArrayList<>(N.size(a));
//
// if (N.isNullOrEmpty(a)) {
// return result;
// } else if (N.isNullOrEmpty(b)) {
// for (T left : a) {
// result.add(Pair.of(left, (U) null));
// }
// } else {
// for (T left : a) {
// boolean joined = false;
//
// for (U right : b) {
// if (predicate.test(left, right)) {
// result.add(Pair.of(left, right));
// joined = true;
// }
// }
//
// if (joined == false) {
// result.add(Pair.of(left, (U) null));
// }
// }
// }
//
// return result;
// }
//
// /**
// * The time complexity is O(n + m) : n is the size of this Seq
and m is the size of specified collection b
.
// *
// * @param the generic type
// * @param the generic type
// * @param the element type
// * @param the generic type
// * @param a the a
// * @param b the b
// * @param leftKeyMapper the left key mapper
// * @param rightKeyMapper the right key mapper
// * @return the list
// * @throws E the e
// * @throws E2 the e2
// * @see N#rightJoin(Collection, Collection, com.landawn.abacus.util.Throwables.Function, com.landawn.abacus.util.Throwables.Function)
// * @see sql join
// * @deprecated replaced by {@code N.rightJoin(Collection, Collection, com.landawn.abacus.util.Try.Function, com.landawn.abacus.util.Try.Function)}
// */
// @Deprecated
// public static List> rightJoin(final Collection a, final Collection b,
// final Throwables.Function super T, ? extends K, E> leftKeyMapper, final Throwables.Function super U, ? extends K, E2> rightKeyMapper)
// throws E, E2 {
// final List> result = new ArrayList<>(N.size(b));
//
// if (N.isNullOrEmpty(b)) {
// return result;
// } else if (N.isNullOrEmpty(a)) {
// for (U right : b) {
// result.add(Pair.of((T) null, right));
// }
// } else {
// final ListMultimap leftKeyMap = ListMultimap.from(a, leftKeyMapper);
//
// for (U right : b) {
// final List lefts = leftKeyMap.get(rightKeyMapper.apply(right));
//
// if (N.notNullOrEmpty(lefts)) {
// for (T left : lefts) {
// result.add(Pair.of(left, right));
// }
// } else {
// result.add(Pair.of((T) null, right));
// }
// }
// }
//
// return result;
// }
//
// /**
// * The time complexity is O(n * m) : n is the size of this Seq
and m is the size of specified collection b
.
// *
// * @param the generic type
// * @param the generic type
// * @param the element type
// * @param a the a
// * @param b the b
// * @param predicate the predicate
// * @return the list
// * @throws E the e
// * @see N#rightJoin(Collection, Collection, com.landawn.abacus.util.Throwables.BiPredicate)
// * @see sql join
// * @deprecated replaced by {@code N.rightJoin(Collection, Collection, com.landawn.abacus.util.Try.BiPredicate)}
// */
// @Deprecated
// public static List> rightJoin(final Collection a, final Collection b,
// final Throwables.BiPredicate super T, ? super U, E> predicate) throws E {
// final List> result = new ArrayList<>(N.size(b));
//
// if (N.isNullOrEmpty(b)) {
// return result;
// } else if (N.isNullOrEmpty(a)) {
// for (U right : b) {
// result.add(Pair.of((T) null, right));
// }
// } else {
// for (U right : b) {
// boolean joined = false;
//
// for (T left : a) {
// if (predicate.test(left, right)) {
// result.add(Pair.of(left, right));
// joined = true;
// }
// }
//
// if (joined == false) {
// result.add(Pair.of((T) null, right));
// }
// }
// }
//
// return result;
// }
@SuppressWarnings("rawtypes")
public static boolean padLeft(final List list, final int minLen, final T objToAdd) {
N.checkArgNotNegative(minLen, "minLen");
final int size = N.size(list);
if (size < minLen) {
final int elementCountToAdd = minLen - size;
final Object[] a = new Object[elementCountToAdd];
if (objToAdd != null) {
N.fill(a, objToAdd);
list.addAll(0, (List) Arrays.asList(a));
}
return true;
}
return false;
}
@SuppressWarnings("rawtypes")
public static boolean padRight(final Collection c, final int minLen, final T objToAdd) {
N.checkArgNotNegative(minLen, "minLen");
final int size = N.size(c);
if (size < minLen) {
final int elementCountToAdd = minLen - size;
final Object[] a = new Object[elementCountToAdd];
if (objToAdd != null) {
N.fill(a, objToAdd);
c.addAll((Collection) Arrays.asList(a));
}
return true;
}
return false;
}
public static abstract class SetView extends ImmutableSet {
SetView(final Set extends E> set) {
super(set);
}
public > S copyInto(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).
*/
public static SetView union(final Set extends E> set1, final Set extends E> set2) {
// N.checkArgNotNull(set1, "set1");
// N.checkArgNotNull(set2, "set2");
Set extends E> tmp = null;
if (set1 == null) {
tmp = set2 == null ? N. emptySet() : set2;
} else if (set2 == null) {
tmp = set1;
} else {
tmp = new AbstractSet() {
@Override
public ObjIterator iterator() {
return new ObjIterator() {
private final Iterator extends E> iter1 = set1.iterator();
private final Iterator extends E> iter2 = set2.iterator();
private final E NONE = (E) N.NULL_MASK;
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() == false) {
throw new NoSuchElementException();
}
if (iter1.hasNext()) {
return iter1.next();
} else {
tmp = next;
next = NONE;
return tmp;
}
}
};
}
@Override
public boolean contains(Object object) {
return set1.contains(object) || set2.contains(object);
}
@Override
public int size() {
int size = set1.size();
for (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(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
*
* This is unfortunate, but should come up only very rarely.
*/
public static SetView intersection(final Set set1, final Set> set2) {
// N.checkArgNotNull(set1, "set1");
// N.checkArgNotNull(set2, "set2");
Set tmp = null;
if (set1 == null || set2 == null) {
tmp = N.