package cn.hutool.core.collection;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.comparator.CompareUtil;
import cn.hutool.core.comparator.PinyinComparator;
import cn.hutool.core.comparator.PropertyComparator;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.convert.ConverterRegistry;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.lang.*;
import cn.hutool.core.lang.func.Func1;
import cn.hutool.core.lang.hash.Hash32;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.*;
import java.io.Serializable;
import java.lang.reflect.Type;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* 集合相关工具类
*
* 此工具方法针对{@link Collection}及其实现类封装的工具。
*
* 由于{@link Collection} 实现了{@link Iterable}接口,因此部分工具此类不提供,而是在{@link IterUtil} 中提供
*
* @author xiaoleilu
* @see IterUtil
* @since 3.1.1
*/
public class CollUtil {
/**
* 如果提供的集合为{@code null},返回一个不可变的默认空集合,否则返回原集合
* 空集合使用{@link Collections#emptySet()}
*
* @param 集合元素类型
* @param set 提供的集合,可能为null
* @return 原集合,若为null返回空集合
* @since 4.6.3
*/
public static Set emptyIfNull(Set set) {
return (null == set) ? Collections.emptySet() : set;
}
/**
* 如果提供的集合为{@code null},返回一个不可变的默认空集合,否则返回原集合
* 空集合使用{@link Collections#emptyList()}
*
* @param 集合元素类型
* @param list 提供的集合,可能为null
* @return 原集合,若为null返回空集合
* @since 4.6.3
*/
public static List emptyIfNull(List list) {
return (null == list) ? Collections.emptyList() : list;
}
/**
* 两个集合的并集
* 针对一个集合中存在多个相同元素的情况,计算两个集合中此元素的个数,保留最多的个数
* 例如:集合1:[a, b, c, c, c],集合2:[a, b, c, c]
* 结果:[a, b, c, c, c],此结果中只保留了三个c
*
* @param 集合元素类型
* @param coll1 集合1
* @param coll2 集合2
* @return 并集的集合,返回 {@link ArrayList}
*/
public static Collection union(Collection coll1, Collection coll2) {
if (isEmpty(coll1) && isEmpty(coll2)) {
return new ArrayList<>();
}
if (isEmpty(coll1)) {
return new ArrayList<>(coll2);
} else if (isEmpty(coll2)) {
return new ArrayList<>(coll1);
}
final ArrayList list = new ArrayList<>(Math.max(coll1.size(), coll2.size()));
final Map map1 = countMap(coll1);
final Map map2 = countMap(coll2);
final Set elts = newHashSet(coll2);
elts.addAll(coll1);
int m;
for (T t : elts) {
m = Math.max(Convert.toInt(map1.get(t), 0), Convert.toInt(map2.get(t), 0));
for (int i = 0; i < m; i++) {
list.add(t);
}
}
return list;
}
/**
* 多个集合的并集
* 针对一个集合中存在多个相同元素的情况,计算两个集合中此元素的个数,保留最多的个数
* 例如:集合1:[a, b, c, c, c],集合2:[a, b, c, c]
* 结果:[a, b, c, c, c],此结果中只保留了三个c
*
* @param 集合元素类型
* @param coll1 集合1
* @param coll2 集合2
* @param otherColls 其它集合
* @return 并集的集合,返回 {@link ArrayList}
*/
@SafeVarargs
public static Collection union(Collection coll1, Collection coll2, Collection... otherColls) {
Collection union = union(coll1, coll2);
for (Collection coll : otherColls) {
if (isEmpty(coll)) {
continue;
}
union = union(union, coll);
}
return union;
}
/**
* 多个集合的非重复并集,类似于SQL中的“UNION DISTINCT”
* 针对一个集合中存在多个相同元素的情况,只保留一个
* 例如:集合1:[a, b, c, c, c],集合2:[a, b, c, c]
* 结果:[a, b, c],此结果中只保留了一个c
*
* @param 集合元素类型
* @param coll1 集合1
* @param coll2 集合2
* @param otherColls 其它集合
* @return 并集的集合,返回 {@link LinkedHashSet}
*/
@SafeVarargs
public static Set unionDistinct(Collection coll1, Collection coll2, Collection... otherColls) {
final Set result;
if (isEmpty(coll1)) {
result = new LinkedHashSet<>();
} else {
result = new LinkedHashSet<>(coll1);
}
if (isNotEmpty(coll2)) {
result.addAll(coll2);
}
if (ArrayUtil.isNotEmpty(otherColls)) {
for (Collection otherColl : otherColls) {
if (isEmpty(otherColl)) {
continue;
}
result.addAll(otherColl);
}
}
return result;
}
/**
* 多个集合的完全并集,类似于SQL中的“UNION ALL”
* 针对一个集合中存在多个相同元素的情况,保留全部元素
* 例如:集合1:[a, b, c, c, c],集合2:[a, b, c, c]
* 结果:[a, b, c, c, c, a, b, c, c]
*
* @param 集合元素类型
* @param coll1 集合1
* @param coll2 集合2
* @param otherColls 其它集合
* @return 并集的集合,返回 {@link ArrayList}
*/
@SafeVarargs
public static List unionAll(Collection coll1, Collection coll2, Collection... otherColls) {
if (CollUtil.isEmpty(coll1) && CollUtil.isEmpty(coll2) && ArrayUtil.isEmpty(otherColls)) {
return new ArrayList<>(0);
}
// 计算元素总数
int totalSize = 0;
totalSize += size(coll1);
totalSize += size(coll2);
if (otherColls != null) {
for (final Collection otherColl : otherColls) {
totalSize += size(otherColl);
}
}
// 根据size创建,防止多次扩容
final List res = new ArrayList<>(totalSize);
if (coll1 != null) {
res.addAll(coll1);
}
if (coll2 != null) {
res.addAll(coll2);
}
if (otherColls == null) {
return res;
}
for (final Collection otherColl : otherColls) {
if (otherColl != null) {
res.addAll(otherColl);
}
}
return res;
}
/**
* 两个集合的交集
* 针对一个集合中存在多个相同元素的情况,计算两个集合中此元素的个数,保留最少的个数
* 例如:集合1:[a, b, c, c, c],集合2:[a, b, c, c]
* 结果:[a, b, c, c],此结果中只保留了两个c
*
* @param 集合元素类型
* @param coll1 集合1
* @param coll2 集合2
* @return 交集的集合,返回 {@link ArrayList}
*/
public static Collection intersection(Collection coll1, Collection coll2) {
if (isNotEmpty(coll1) && isNotEmpty(coll2)) {
final ArrayList list = new ArrayList<>(Math.min(coll1.size(), coll2.size()));
final Map map1 = countMap(coll1);
final Map map2 = countMap(coll2);
final Set elts = newHashSet(coll2);
int m;
for (T t : elts) {
m = Math.min(Convert.toInt(map1.get(t), 0), Convert.toInt(map2.get(t), 0));
for (int i = 0; i < m; i++) {
list.add(t);
}
}
return list;
}
return new ArrayList<>();
}
/**
* 多个集合的交集
* 针对一个集合中存在多个相同元素的情况,计算两个集合中此元素的个数,保留最少的个数
* 例如:集合1:[a, b, c, c, c],集合2:[a, b, c, c]
* 结果:[a, b, c, c],此结果中只保留了两个c
*
* @param 集合元素类型
* @param coll1 集合1
* @param coll2 集合2
* @param otherColls 其它集合
* @return 交集的集合,返回 {@link ArrayList}
*/
@SafeVarargs
public static Collection intersection(Collection coll1, Collection coll2, Collection... otherColls) {
Collection intersection = intersection(coll1, coll2);
if (isEmpty(intersection)) {
return intersection;
}
for (Collection coll : otherColls) {
intersection = intersection(intersection, coll);
if (isEmpty(intersection)) {
return intersection;
}
}
return intersection;
}
/**
* 多个集合的交集
* 针对一个集合中存在多个相同元素的情况,只保留一个
* 例如:集合1:[a, b, c, c, c],集合2:[a, b, c, c]
* 结果:[a, b, c],此结果中只保留了一个c
*
* @param 集合元素类型
* @param coll1 集合1
* @param coll2 集合2
* @param otherColls 其它集合
* @return 交集的集合,返回 {@link LinkedHashSet}
* @since 5.3.9
*/
@SafeVarargs
public static Set intersectionDistinct(Collection coll1, Collection coll2, Collection... otherColls) {
final Set result;
if (isEmpty(coll1) || isEmpty(coll2)) {
// 有一个空集合就直接返回空
return new LinkedHashSet<>();
} else {
result = new LinkedHashSet<>(coll1);
}
if (ArrayUtil.isNotEmpty(otherColls)) {
for (Collection otherColl : otherColls) {
if (isNotEmpty(otherColl)) {
result.retainAll(otherColl);
} else {
// 有一个空集合就直接返回空
return new LinkedHashSet<>();
}
}
}
result.retainAll(coll2);
return result;
}
/**
* 两个集合的差集
* 针对一个集合中存在多个相同元素的情况,计算两个集合中此元素的个数,保留两个集合中此元素个数差的个数
* 例如:
*
*
* disjunction([a, b, c, c, c], [a, b, c, c]) -》 [c]
* disjunction([a, b], []) -》 [a, b]
* disjunction([a, b, c], [b, c, d]) -》 [a, d]
*
* 任意一个集合为空,返回另一个集合
* 两个集合无差集则返回空集合
*
* @param 集合元素类型
* @param coll1 集合1
* @param coll2 集合2
* @return 差集的集合,返回 {@link ArrayList}
*/
public static Collection disjunction(Collection coll1, Collection coll2) {
if (isEmpty(coll1)) {
return coll2;
}
if (isEmpty(coll2)) {
return coll1;
}
final List result = new ArrayList<>();
final Map map1 = countMap(coll1);
final Map map2 = countMap(coll2);
final Set elts = newHashSet(coll2);
elts.addAll(coll1);
int m;
for (T t : elts) {
m = Math.abs(Convert.toInt(map1.get(t), 0) - Convert.toInt(map2.get(t), 0));
for (int i = 0; i < m; i++) {
result.add(t);
}
}
return result;
}
/**
* 计算集合的单差集,即只返回【集合1】中有,但是【集合2】中没有的元素,例如:
*
*
* subtract([1,2,3,4],[2,3,4,5]) -》 [1]
*
*
* @param coll1 集合1
* @param coll2 集合2
* @param 元素类型
* @return 单差集
*/
public static Collection subtract(Collection coll1, Collection coll2) {
Collection result = ObjectUtil.clone(coll1);
try {
if (null == result) {
result = CollUtil.create(coll1.getClass());
result.addAll(coll1);
}
result.removeAll(coll2);
} catch (UnsupportedOperationException e) {
// 针对 coll1 为只读集合的补偿
result = CollUtil.create(AbstractCollection.class);
result.addAll(coll1);
result.removeAll(coll2);
}
return result;
}
/**
* 计算集合的单差集,即只返回【集合1】中有,但是【集合2】中没有的元素,例如:
*
*
* subtractToList([1,2,3,4],[2,3,4,5]) -》 [1]
*
*
* @param coll1 集合1
* @param coll2 集合2
* @param 元素类型
* @return 单差集
* @since 5.3.5
*/
public static List subtractToList(Collection coll1, Collection coll2) {
if (isEmpty(coll1)) {
return ListUtil.empty();
}
if (isEmpty(coll2)) {
return ListUtil.list(true, coll1);
}
//将被交数用链表储存,防止因为频繁扩容影响性能
final List result = new LinkedList<>();
Set set = new HashSet<>(coll2);
for (T t : coll1) {
if (false == set.contains(t)) {
result.add(t);
}
}
return result;
}
/**
* 判断指定集合是否包含指定值,如果集合为空(null或者空),返回{@code false},否则找到元素返回{@code true}
*
* @param collection 集合
* @param value 需要查找的值
* @return 如果集合为空(null或者空),返回{@code false},否则找到元素返回{@code true}
* @throws ClassCastException 如果类型不一致会抛出转换异常
* @throws NullPointerException 当指定的元素 值为 null ,或集合类不支持null 时抛出该异常
* @see Collection#contains(Object)
* @since 4.1.10
*/
public static boolean contains(Collection> collection, Object value) {
return isNotEmpty(collection) && collection.contains(value);
}
/**
* 判断指定集合是否包含指定值,如果集合为空(null或者空),返回{@code false},否则找到元素返回{@code true}
*
* @param collection 集合
* @param value 需要查找的值
* @return 果集合为空(null或者空),返回{@code false},否则找到元素返回{@code true}
* @since 5.7.16
*/
public static boolean safeContains(Collection> collection, Object value) {
try {
return contains(collection, value);
} catch (ClassCastException | NullPointerException e) {
return false;
}
}
/**
* 自定义函数判断集合是否包含某类值
*
* @param collection 集合
* @param containFunc 自定义判断函数
* @param 值类型
* @return 是否包含自定义规则的值
*/
public static boolean contains(Collection collection, Predicate super T> containFunc) {
if (isEmpty(collection)) {
return false;
}
for (T t : collection) {
if (containFunc.test(t)) {
return true;
}
}
return false;
}
/**
* 其中一个集合在另一个集合中是否至少包含一个元素,即是两个集合是否至少有一个共同的元素
*
* @param coll1 集合1
* @param coll2 集合2
* @return 其中一个集合在另一个集合中是否至少包含一个元素
* @see #intersection
* @since 2.1
*/
public static boolean containsAny(Collection> coll1, Collection> coll2) {
if (isEmpty(coll1) || isEmpty(coll2)) {
return false;
}
if (coll1.size() < coll2.size()) {
for (Object object : coll1) {
if (coll2.contains(object)) {
return true;
}
}
} else {
for (Object object : coll2) {
if (coll1.contains(object)) {
return true;
}
}
}
return false;
}
/**
* 集合1中是否包含集合2中所有的元素。
* 当集合1和集合2都为空时,返回{@code true}
* 当集合2为空时,返回{@code true}
*
* @param coll1 集合1
* @param coll2 集合2
* @return 集合1中是否包含集合2中所有的元素
* @since 4.5.12
*/
@SuppressWarnings("SuspiciousMethodCalls")
public static boolean containsAll(Collection> coll1, Collection> coll2) {
if (isEmpty(coll1)) {
return isEmpty(coll2);
}
if (isEmpty(coll2)) {
return true;
}
// Set直接判定
if(coll1 instanceof Set){
return coll1.containsAll(coll2);
}
// 参考Apache commons collection4
// 将时间复杂度降低到O(n + m)
final Iterator> it = coll1.iterator();
final Set elementsAlreadySeen = new HashSet<>(coll1.size(), 1);
for (final Object nextElement : coll2) {
if (elementsAlreadySeen.contains(nextElement)) {
continue;
}
boolean foundCurrentElement = false;
while (it.hasNext()) {
final Object p = it.next();
elementsAlreadySeen.add(p);
if (Objects.equals(nextElement, p)) {
foundCurrentElement = true;
break;
}
}
if (false == foundCurrentElement) {
return false;
}
}
return true;
}
/**
* 根据集合返回一个元素计数的 {@link Map}
* 所谓元素计数就是假如这个集合中某个元素出现了n次,那将这个元素做为key,n做为value
* 例如:[a,b,c,c,c] 得到:
* a: 1
* b: 1
* c: 3
*
* @param 集合元素类型
* @param collection 集合
* @return {@link Map}
* @see IterUtil#countMap(Iterator)
*/
public static Map countMap(Iterable collection) {
return IterUtil.countMap(null == collection ? null : collection.iterator());
}
/**
* 以 conjunction 为分隔符将集合转换为字符串
*
* @param 集合元素类型
* @param iterable {@link Iterable}
* @param conjunction 分隔符
* @param func 集合元素转换器,将元素转换为字符串
* @return 连接后的字符串
* @see IterUtil#join(Iterator, CharSequence, Function)
* @since 5.6.7
*/
public static String join(Iterable iterable, CharSequence conjunction, Function func) {
if (null == iterable) {
return null;
}
return IterUtil.join(iterable.iterator(), conjunction, func);
}
/**
* 以 conjunction 为分隔符将集合转换为字符串
* 如果集合元素为数组、{@link Iterable}或{@link Iterator},则递归组合其为字符串
*
* @param 集合元素类型
* @param iterable {@link Iterable}
* @param conjunction 分隔符
* @return 连接后的字符串
* @see IterUtil#join(Iterator, CharSequence)
*/
public static String join(Iterable iterable, CharSequence conjunction) {
if (null == iterable) {
return null;
}
return IterUtil.join(iterable.iterator(), conjunction);
}
/**
* 以 conjunction 为分隔符将集合转换为字符串
*
* @param 集合元素类型
* @param iterable {@link Iterable}
* @param conjunction 分隔符
* @param prefix 每个元素添加的前缀,null表示不添加
* @param suffix 每个元素添加的后缀,null表示不添加
* @return 连接后的字符串
* @since 5.3.0
*/
public static String join(Iterable iterable, CharSequence conjunction, String prefix, String suffix) {
if (null == iterable) {
return null;
}
return IterUtil.join(iterable.iterator(), conjunction, prefix, suffix);
}
/**
* 以 conjunction 为分隔符将集合转换为字符串
* 如果集合元素为数组、{@link Iterable}或{@link Iterator},则递归组合其为字符串
*
* @param 集合元素类型
* @param iterator 集合
* @param conjunction 分隔符
* @return 连接后的字符串
* @deprecated 请使用IterUtil#join(Iterator, CharSequence)
*/
@Deprecated
public static String join(Iterator iterator, CharSequence conjunction) {
return IterUtil.join(iterator, conjunction);
}
/**
* 切取部分数据
* 切取后的栈将减少这些元素
*
* @param 集合元素类型
* @param surplusAlaDatas 原数据
* @param partSize 每部分数据的长度
* @return 切取出的数据或null
*/
public static List popPart(Stack surplusAlaDatas, int partSize) {
if (isEmpty(surplusAlaDatas)) {
return ListUtil.empty();
}
final List currentAlaDatas = new ArrayList<>();
int size = surplusAlaDatas.size();
// 切割
if (size > partSize) {
for (int i = 0; i < partSize; i++) {
currentAlaDatas.add(surplusAlaDatas.pop());
}
} else {
for (int i = 0; i < size; i++) {
currentAlaDatas.add(surplusAlaDatas.pop());
}
}
return currentAlaDatas;
}
/**
* 切取部分数据
* 切取后的栈将减少这些元素
*
* @param 集合元素类型
* @param surplusAlaDatas 原数据
* @param partSize 每部分数据的长度
* @return 切取出的数据或null
*/
public static List popPart(Deque surplusAlaDatas, int partSize) {
if (isEmpty(surplusAlaDatas)) {
return ListUtil.empty();
}
final List currentAlaDatas = new ArrayList<>();
int size = surplusAlaDatas.size();
// 切割
if (size > partSize) {
for (int i = 0; i < partSize; i++) {
currentAlaDatas.add(surplusAlaDatas.pop());
}
} else {
for (int i = 0; i < size; i++) {
currentAlaDatas.add(surplusAlaDatas.pop());
}
}
return currentAlaDatas;
}
/**
* 是否至少有一个符合判断条件
*
* @param 集合元素类型
* @param collection 集合
* @param predicate 自定义判断函数
* @return 是否有一个值匹配 布尔值
*/
public static boolean anyMatch(Collection collection,Predicate predicate){
if(isEmpty(collection)){
return Boolean.FALSE;
}
return collection.stream().anyMatch(predicate);
}
/**
* 是否全部匹配判断条件
*
* @param 集合元素类型
* @param collection 集合
* @param predicate 自定义判断函数
* @return 是否全部匹配 布尔值
*/
public static boolean allMatch(Collection collection,Predicate predicate){
if(isEmpty(collection)){
return Boolean.FALSE;
}
return collection.stream().allMatch(predicate);
}
// ----------------------------------------------------------------------------------------------- new HashSet
/**
* 新建一个HashSet
*
* @param 集合元素类型
* @param ts 元素数组
* @return HashSet对象
*/
@SafeVarargs
public static HashSet newHashSet(T... ts) {
return set(false, ts);
}
/**
* 新建一个LinkedHashSet
*
* @param 集合元素类型
* @param ts 元素数组
* @return HashSet对象
* @since 4.1.10
*/
@SafeVarargs
public static LinkedHashSet newLinkedHashSet(T... ts) {
return (LinkedHashSet) set(true, ts);
}
/**
* 新建一个HashSet
*
* @param 集合元素类型
* @param isSorted 是否有序,有序返回 {@link LinkedHashSet},否则返回 {@link HashSet}
* @param ts 元素数组
* @return HashSet对象
*/
@SafeVarargs
public static HashSet set(boolean isSorted, T... ts) {
if (null == ts) {
return isSorted ? new LinkedHashSet<>() : new HashSet<>();
}
int initialCapacity = Math.max((int) (ts.length / .75f) + 1, 16);
final HashSet set = isSorted ? new LinkedHashSet<>(initialCapacity) : new HashSet<>(initialCapacity);
Collections.addAll(set, ts);
return set;
}
/**
* 新建一个HashSet
*
* @param 集合元素类型
* @param collection 集合
* @return HashSet对象
*/
public static HashSet newHashSet(Collection collection) {
return newHashSet(false, collection);
}
/**
* 新建一个HashSet
*
* @param 集合元素类型
* @param isSorted 是否有序,有序返回 {@link LinkedHashSet},否则返回{@link HashSet}
* @param collection 集合,用于初始化Set
* @return HashSet对象
*/
public static HashSet newHashSet(boolean isSorted, Collection collection) {
return isSorted ? new LinkedHashSet<>(collection) : new HashSet<>(collection);
}
/**
* 新建一个HashSet
*
* @param 集合元素类型
* @param isSorted 是否有序,有序返回 {@link LinkedHashSet},否则返回{@link HashSet}
* @param iter {@link Iterator}
* @return HashSet对象
* @since 3.0.8
*/
public static HashSet newHashSet(boolean isSorted, Iterator iter) {
if (null == iter) {
return set(isSorted, (T[]) null);
}
final HashSet set = isSorted ? new LinkedHashSet<>() : new HashSet<>();
while (iter.hasNext()) {
set.add(iter.next());
}
return set;
}
/**
* 新建一个HashSet
*
* @param 集合元素类型
* @param isSorted 是否有序,有序返回 {@link LinkedHashSet},否则返回{@link HashSet}
* @param enumeration {@link Enumeration}
* @return HashSet对象
* @since 3.0.8
*/
public static HashSet newHashSet(boolean isSorted, Enumeration enumeration) {
if (null == enumeration) {
return set(isSorted, (T[]) null);
}
final HashSet set = isSorted ? new LinkedHashSet<>() : new HashSet<>();
while (enumeration.hasMoreElements()) {
set.add(enumeration.nextElement());
}
return set;
}
// ----------------------------------------------------------------------------------------------- List
/**
* 新建一个空List
*
* @param 集合元素类型
* @param isLinked 是否新建LinkedList
* @return List对象
* @since 4.1.2
*/
public static List list(boolean isLinked) {
return ListUtil.list(isLinked);
}
/**
* 新建一个List
*
* @param 集合元素类型
* @param isLinked 是否新建LinkedList
* @param values 数组
* @return List对象
* @since 4.1.2
*/
@SafeVarargs
public static List list(boolean isLinked, T... values) {
return ListUtil.list(isLinked, values);
}
/**
* 新建一个List
*
* @param 集合元素类型
* @param isLinked 是否新建LinkedList
* @param collection 集合
* @return List对象
* @since 4.1.2
*/
public static List list(boolean isLinked, Collection collection) {
return ListUtil.list(isLinked, collection);
}
/**
* 新建一个List
* 提供的参数为null时返回空{@link ArrayList}
*
* @param 集合元素类型
* @param isLinked 是否新建LinkedList
* @param iterable {@link Iterable}
* @return List对象
* @since 4.1.2
*/
public static List list(boolean isLinked, Iterable iterable) {
return ListUtil.list(isLinked, iterable);
}
/**
* 新建一个ArrayList
* 提供的参数为null时返回空{@link ArrayList}
*
* @param 集合元素类型
* @param isLinked 是否新建LinkedList
* @param iter {@link Iterator}
* @return ArrayList对象
* @since 4.1.2
*/
public static List list(boolean isLinked, Iterator iter) {
return ListUtil.list(isLinked, iter);
}
/**
* 新建一个List
* 提供的参数为null时返回空{@link ArrayList}
*
* @param 集合元素类型
* @param isLinked 是否新建LinkedList
* @param enumeration {@link Enumeration}
* @return ArrayList对象
* @since 3.0.8
*/
public static List list(boolean isLinked, Enumeration enumeration) {
return ListUtil.list(isLinked, enumeration);
}
/**
* 新建一个ArrayList
*
* @param 集合元素类型
* @param values 数组
* @return ArrayList对象
* @see #toList(Object[])
*/
@SafeVarargs
public static ArrayList newArrayList(T... values) {
return ListUtil.toList(values);
}
/**
* 数组转为ArrayList
*
* @param 集合元素类型
* @param values 数组
* @return ArrayList对象
* @since 4.0.11
*/
@SafeVarargs
public static ArrayList toList(T... values) {
return ListUtil.toList(values);
}
/**
* 新建一个ArrayList
*
* @param 集合元素类型
* @param collection 集合
* @return ArrayList对象
*/
public static ArrayList newArrayList(Collection collection) {
return ListUtil.toList(collection);
}
/**
* 新建一个ArrayList
* 提供的参数为null时返回空{@link ArrayList}
*
* @param 集合元素类型
* @param iterable {@link Iterable}
* @return ArrayList对象
* @since 3.1.0
*/
public static ArrayList newArrayList(Iterable iterable) {
return ListUtil.toList(iterable);
}
/**
* 新建一个ArrayList
* 提供的参数为null时返回空{@link ArrayList}
*
* @param 集合元素类型
* @param iterator {@link Iterator}
* @return ArrayList对象
* @since 3.0.8
*/
public static ArrayList newArrayList(Iterator iterator) {
return ListUtil.toList(iterator);
}
/**
* 新建一个ArrayList
* 提供的参数为null时返回空{@link ArrayList}
*
* @param 集合元素类型
* @param enumeration {@link Enumeration}
* @return ArrayList对象
* @since 3.0.8
*/
public static ArrayList newArrayList(Enumeration enumeration) {
return ListUtil.toList(enumeration);
}
// ----------------------------------------------------------------------new LinkedList
/**
* 新建LinkedList
*
* @param values 数组
* @param 类型
* @return LinkedList
* @since 4.1.2
*/
@SafeVarargs
public static LinkedList newLinkedList(T... values) {
return ListUtil.toLinkedList(values);
}
/**
* 新建一个CopyOnWriteArrayList
*
* @param 集合元素类型
* @param collection 集合
* @return {@link CopyOnWriteArrayList}
*/
public static CopyOnWriteArrayList newCopyOnWriteArrayList(Collection collection) {
return ListUtil.toCopyOnWriteArrayList(collection);
}
/**
* 新建{@link BlockingQueue}
* 在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。
*
* @param 集合类型
* @param capacity 容量
* @param isLinked 是否为链表形式
* @return {@link BlockingQueue}
* @since 3.3.0
*/
public static BlockingQueue newBlockingQueue(int capacity, boolean isLinked) {
final BlockingQueue queue;
if (isLinked) {
queue = new LinkedBlockingDeque<>(capacity);
} else {
queue = new ArrayBlockingQueue<>(capacity);
}
return queue;
}
/**
* 创建新的集合对象
*
* @param 集合类型
* @param collectionType 集合类型
* @return 集合类型对应的实例
* @since 3.0.8
*/
public static Collection create(Class> collectionType) {
return create(collectionType, null);
}
/**
* 创建新的集合对象,返回具体的泛型集合
*
* @param 集合元素类型
* @param collectionType 集合类型,rawtype 如 ArrayList.class, EnumSet.class ...
* @param elementType 集合元素类型
* @return 集合类型对应的实例
* @since v5
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public static Collection create(Class> collectionType, Class elementType) {
final Collection list;
if (collectionType.isAssignableFrom(AbstractCollection.class)) {
// 抽象集合默认使用ArrayList
list = new ArrayList<>();
}
// Set
else if (collectionType.isAssignableFrom(HashSet.class)) {
list = new HashSet<>();
} else if (collectionType.isAssignableFrom(LinkedHashSet.class)) {
list = new LinkedHashSet<>();
} else if (collectionType.isAssignableFrom(TreeSet.class)) {
list = new TreeSet<>((o1, o2) -> {
// 优先按照对象本身比较,如果没有实现比较接口,默认按照toString内容比较
if (o1 instanceof Comparable) {
return ((Comparable) o1).compareTo(o2);
}
return CompareUtil.compare(o1.toString(), o2.toString());
});
} else if (collectionType.isAssignableFrom(EnumSet.class)) {
list = (Collection) EnumSet.noneOf(Assert.notNull((Class) elementType));
}
// List
else if (collectionType.isAssignableFrom(ArrayList.class)) {
list = new ArrayList<>();
} else if (collectionType.isAssignableFrom(LinkedList.class)) {
list = new LinkedList<>();
}
// Others,直接实例化
else {
try {
list = (Collection) ReflectUtil.newInstance(collectionType);
} catch (final Exception e) {
// 无法创建当前类型的对象,尝试创建父类型对象
final Class> superclass = collectionType.getSuperclass();
if (null != superclass && collectionType != superclass) {
return create(superclass);
}
throw new UtilException(e);
}
}
return list;
}
/**
* 去重集合
*
* @param 集合元素类型
* @param collection 集合
* @return {@link ArrayList}
*/
public static ArrayList distinct(Collection collection) {
if (isEmpty(collection)) {
return new ArrayList<>();
} else if (collection instanceof Set) {
return new ArrayList<>(collection);
} else {
return new ArrayList<>(new LinkedHashSet<>(collection));
}
}
/**
* 根据函数生成的KEY去重集合,如根据Bean的某个或者某些字段完成去重。
* 去重可选是保留最先加入的值还是后加入的值
*
* @param 集合元素类型
* @param 唯一键类型
* @param collection 集合
* @param uniqueGenerator 唯一键生成器
* @param override 是否覆盖模式,如果为{@code true},加入的新值会覆盖相同key的旧值,否则会忽略新加值
* @return {@link ArrayList}
* @since 5.8.0
*/
public static List distinct(Collection collection, Function uniqueGenerator, boolean override) {
if (isEmpty(collection)) {
return new ArrayList<>();
}
final UniqueKeySet set = new UniqueKeySet<>(true, uniqueGenerator);
if (override) {
set.addAll(collection);
} else {
set.addAllIfAbsent(collection);
}
return new ArrayList<>(set);
}
/**
* 截取列表的部分
*
* @param 集合元素类型
* @param list 被截取的数组
* @param start 开始位置(包含)
* @param end 结束位置(不包含)
* @return 截取后的数组,当开始位置超过最大时,返回空的List
* @see ListUtil#sub(List, int, int)
*/
public static List sub(List list, int start, int end) {
return ListUtil.sub(list, start, end);
}
/**
* 截取列表的部分
*
* @param 集合元素类型
* @param list 被截取的数组
* @param start 开始位置(包含)
* @param end 结束位置(不包含)
* @param step 步进
* @return 截取后的数组,当开始位置超过最大时,返回空的List
* @see ListUtil#sub(List, int, int, int)
* @since 4.0.6
*/
public static List sub(List list, int start, int end, int step) {
return ListUtil.sub(list, start, end, step);
}
/**
* 截取集合的部分
*
* @param 集合元素类型
* @param collection 被截取的数组
* @param start 开始位置(包含)
* @param end 结束位置(不包含)
* @return 截取后的数组,当开始位置超过最大时,返回null
*/
public static List sub(Collection collection, int start, int end) {
return sub(collection, start, end, 1);
}
/**
* 截取集合的部分
*
* @param 集合元素类型
* @param collection 被截取的数组
* @param start 开始位置(包含)
* @param end 结束位置(不包含)
* @param step 步进
* @return 截取后的数组,当开始位置超过最大时,返回空集合
* @since 4.0.6
*/
public static List