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

cn.hutool.core.collection.CollUtil Maven / Gradle / Ivy

There is a newer version: 5.8.33
Show newest version
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 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 sub(Collection collection, int start, int end, int step) { if (isEmpty(collection)) { return ListUtil.empty(); } final List list = collection instanceof List ? (List) collection : ListUtil.toList(collection); return sub(list, start, end, step); } /** * 对集合按照指定长度分段,每一个段为单独的集合,返回这个集合的列表 *

* 需要特别注意的是,此方法调用{@link List#subList(int, int)}切分List, * 此方法返回的是原List的视图,也就是说原List有变更,切分后的结果也会变更。 *

* * @param 集合元素类型 * @param list 列表 * @param size 每个段的长度 * @return 分段列表 * @since 5.4.5 * @deprecated 请使用 {@link ListUtil#partition(List, int)} */ @Deprecated public static List> splitList(List list, int size) { return ListUtil.partition(list, size); } /** * 对集合按照指定长度分段,每一个段为单独的集合,返回这个集合的列表 * * @param 集合元素类型 * @param collection 集合 * @param size 每个段的长度 * @return 分段列表 */ public static List> split(Collection collection, int size) { final List> result = new ArrayList<>(); if (CollUtil.isEmpty(collection)) { return result; } final int initSize = Math.min(collection.size(), size); List subList = new ArrayList<>(initSize); for (T t : collection) { if (subList.size() >= size) { result.add(subList); subList = new ArrayList<>(initSize); } subList.add(t); } result.add(subList); return result; } /** * 编辑,此方法产生一个新集合
* 编辑过程通过传入的Editor实现来返回需要的元素内容,这个Editor实现可以实现以下功能: * *
	 * 1、过滤出需要的对象,如果返回null表示这个元素对象抛弃
	 * 2、修改元素对象,返回集合中为修改后的对象
	 * 
* * @param 集合元素类型 * @param collection 集合 * @param editor 编辑器接口,{@code null}返回原集合 * @return 过滤后的集合 */ public static Collection edit(Collection collection, Editor editor) { if (null == collection || null == editor) { return collection; } final Collection collection2 = create(collection.getClass()); if (isEmpty(collection)) { return collection2; } T modified; for (T t : collection) { modified = editor.edit(t); if (null != modified) { collection2.add(modified); } } return collection2; } /** * 过滤
* 过滤过程通过传入的Filter实现来过滤返回需要的元素内容,这个Filter实现可以实现以下功能: * *
	 * 1、过滤出需要的对象,{@link Filter#accept(Object)}方法返回true的对象将被加入结果集合中
	 * 
* * @param 集合元素类型 * @param collection 集合 * @param filter 过滤器,{@code null}返回原集合 * @return 过滤后的数组 * @since 3.1.0 */ public static Collection filterNew(Collection collection, Filter filter) { if (null == collection || null == filter) { return collection; } return edit(collection, t -> filter.accept(t) ? t : null); } /** * 去掉集合中的多个元素,此方法直接修改原集合 * * @param 集合类型 * @param 集合元素类型 * @param collection 集合 * @param elesRemoved 被去掉的元素数组 * @return 原集合 * @since 4.1.0 */ @SuppressWarnings("unchecked") public static , E> T removeAny(T collection, E... elesRemoved) { collection.removeAll(newHashSet(elesRemoved)); return collection; } /** * 去除指定元素,此方法直接修改原集合 * * @param 集合类型 * @param 集合元素类型 * @param collection 集合 * @param filter 过滤器 * @return 处理后的集合 * @since 4.6.5 */ public static , E> T filter(T collection, final Filter filter) { return IterUtil.filter(collection, filter); } /** * 去除{@code null} 元素,此方法直接修改原集合 * * @param 集合类型 * @param 集合元素类型 * @param collection 集合 * @return 处理后的集合 * @since 3.2.2 */ public static , E> T removeNull(T collection) { return filter(collection, Objects::nonNull); } /** * 去除{@code null}或者"" 元素,此方法直接修改原集合 * * @param 集合类型 * @param 集合元素类型 * @param collection 集合 * @return 处理后的集合 * @since 3.2.2 */ public static , E extends CharSequence> T removeEmpty(T collection) { return filter(collection, StrUtil::isNotEmpty); } /** * 去除{@code null}或者""或者空白字符串 元素,此方法直接修改原集合 * * @param 集合类型 * @param 集合元素类型 * @param collection 集合 * @return 处理后的集合 * @since 3.2.2 */ public static , E extends CharSequence> T removeBlank(T collection) { return filter(collection, StrUtil::isNotBlank); } /** * 移除集合中的多个元素,并将结果存放到指定的集合 * 此方法直接修改原集合 * * @param 集合类型 * @param 集合元素类型 * @param resultCollection 存放移除结果的集合 * @param targetCollection 被操作移除元素的集合 * @param predicate 用于是否移除判断的过滤器 * @return 移除结果的集合 * @since 5.7.17 */ public static , E> T removeWithAddIf(T targetCollection, T resultCollection, Predicate predicate) { Objects.requireNonNull(predicate); final Iterator each = targetCollection.iterator(); while (each.hasNext()) { E next = each.next(); if (predicate.test(next)) { resultCollection.add(next); each.remove(); } } return resultCollection; } /** * 移除集合中的多个元素,并将结果存放到生成的新集合中后返回
* 此方法直接修改原集合 * * @param 集合类型 * @param 集合元素类型 * @param targetCollection 被操作移除元素的集合 * @param predicate 用于是否移除判断的过滤器 * @return 移除结果的集合 * @since 5.7.17 */ public static , E> List removeWithAddIf(T targetCollection, Predicate predicate) { final List removed = new ArrayList<>(); removeWithAddIf(targetCollection, removed, predicate); return removed; } /** * 通过Editor抽取集合元素中的某些值返回为新列表
* 例如提供的是一个Bean列表,通过Editor接口实现获取某个字段值,返回这个字段值组成的新列表 * * @param collection 原集合 * @param editor 编辑器 * @return 抽取后的新列表 */ public static List extract(Iterable collection, Editor editor) { return extract(collection, editor, false); } /** * 通过Editor抽取集合元素中的某些值返回为新列表
* 例如提供的是一个Bean列表,通过Editor接口实现获取某个字段值,返回这个字段值组成的新列表 * * @param collection 原集合 * @param editor 编辑器 * @param ignoreNull 是否忽略空值 * @return 抽取后的新列表 * @see #map(Iterable, Function, boolean) * @since 4.5.7 */ public static List extract(Iterable collection, Editor editor, boolean ignoreNull) { return map(collection, editor::edit, ignoreNull); } /** * 通过func自定义一个规则,此规则将原集合中的元素转换成新的元素,生成新的列表返回
* 例如提供的是一个Bean列表,通过Function接口实现获取某个字段值,返回这个字段值组成的新列表 * * @param 集合元素类型 * @param 返回集合元素类型 * @param collection 原集合 * @param func 编辑函数 * @param ignoreNull 是否忽略空值,这里的空值包括函数处理前和处理后的null值 * @return 抽取后的新列表 * @since 5.3.5 */ public static List map(Iterable collection, Function func, boolean ignoreNull) { final List fieldValueList = new ArrayList<>(); if (null == collection) { return fieldValueList; } R value; for (T t : collection) { if (null == t && ignoreNull) { continue; } value = func.apply(t); if (null == value && ignoreNull) { continue; } fieldValueList.add(value); } return fieldValueList; } /** * 获取给定Bean列表中指定字段名对应字段值的列表
* 列表元素支持Bean与Map * * @param collection Bean集合或Map集合 * @param fieldName 字段名或map的键 * @return 字段值列表 * @since 3.1.0 */ public static List getFieldValues(Iterable collection, final String fieldName) { return getFieldValues(collection, fieldName, false); } /** * 获取给定Bean列表中指定字段名对应字段值的列表
* 列表元素支持Bean与Map * * @param collection Bean集合或Map集合 * @param fieldName 字段名或map的键 * @param ignoreNull 是否忽略值为{@code null}的字段 * @return 字段值列表 * @since 4.5.7 */ public static List getFieldValues(Iterable collection, final String fieldName, boolean ignoreNull) { return map(collection, bean -> { if (bean instanceof Map) { return ((Map) bean).get(fieldName); } else { return ReflectUtil.getFieldValue(bean, fieldName); } }, ignoreNull); } /** * 获取给定Bean列表中指定字段名对应字段值的列表
* 列表元素支持Bean与Map * * @param 元素类型 * @param collection Bean集合或Map集合 * @param fieldName 字段名或map的键 * @param elementType 元素类型类 * @return 字段值列表 * @since 4.5.6 */ public static List getFieldValues(Iterable collection, final String fieldName, final Class elementType) { List fieldValues = getFieldValues(collection, fieldName); return Convert.toList(elementType, fieldValues); } /** * 字段值与列表值对应的Map,常用于元素对象中有唯一ID时需要按照这个ID查找对象的情况
* 例如:车牌号 =》车 * * @param 字段名对应值得类型,不确定请使用Object * @param 对象类型 * @param iterable 对象列表 * @param fieldName 字段名(会通过反射获取其值) * @return 某个字段值与对象对应Map * @since 5.0.6 */ public static Map fieldValueMap(Iterable iterable, String fieldName) { return IterUtil.fieldValueMap(IterUtil.getIter(iterable), fieldName); } /** * 两个字段值组成新的Map * * @param 字段名对应值得类型,不确定请使用Object * @param 值类型,不确定使用Object * @param iterable 对象列表 * @param fieldNameForKey 做为键的字段名(会通过反射获取其值) * @param fieldNameForValue 做为值的字段名(会通过反射获取其值) * @return 某个字段值与对象对应Map * @since 5.0.6 */ public static Map fieldValueAsMap(Iterable iterable, String fieldNameForKey, String fieldNameForValue) { return IterUtil.fieldValueAsMap(IterUtil.getIter(iterable), fieldNameForKey, fieldNameForValue); } /** * 查找第一个匹配元素对象 * * @param 集合元素类型 * @param collection 集合 * @param filter 过滤器,满足过滤条件的第一个元素将被返回 * @return 满足过滤条件的第一个元素 * @since 3.1.0 */ public static T findOne(Iterable collection, Filter filter) { if (null != collection) { for (T t : collection) { if (filter.accept(t)) { return t; } } } return null; } /** * 查找第一个匹配元素对象
* 如果集合元素是Map,则比对键和值是否相同,相同则返回
* 如果为普通Bean,则通过反射比对元素字段名对应的字段值是否相同,相同则返回
* 如果给定字段值参数是{@code null} 且元素对象中的字段值也为{@code null}则认为相同 * * @param 集合元素类型 * @param collection 集合,集合元素可以是Bean或者Map * @param fieldName 集合元素对象的字段名或map的键 * @param fieldValue 集合元素对象的字段值或map的值 * @return 满足条件的第一个元素 * @since 3.1.0 */ public static T findOneByField(Iterable collection, final String fieldName, final Object fieldValue) { return findOne(collection, t -> { if (t instanceof Map) { final Map map = (Map) t; final Object value = map.get(fieldName); return ObjectUtil.equal(value, fieldValue); } // 普通Bean final Object value = ReflectUtil.getFieldValue(t, fieldName); return ObjectUtil.equal(value, fieldValue); }); } /** * 集合中匹配规则的数量 * * @param 集合元素类型 * @param iterable {@link Iterable} * @param matcher 匹配器,为空则全部匹配 * @return 匹配数量 */ public static int count(Iterable iterable, Matcher matcher) { int count = 0; if (null != iterable) { for (T t : iterable) { if (null == matcher || matcher.match(t)) { count++; } } } return count; } /** * 获取匹配规则定义中匹配到元素的第一个位置
* 此方法对于某些无序集合的位置信息,以转换为数组后的位置为准。 * * @param 元素类型 * @param collection 集合 * @param matcher 匹配器,为空则全部匹配 * @return 第一个位置 * @since 5.6.6 */ public static int indexOf(Collection collection, Matcher matcher) { if (isNotEmpty(collection)) { int index = 0; for (T t : collection) { if (null == matcher || matcher.match(t)) { return index; } index++; } } return -1; } /** * 获取匹配规则定义中匹配到元素的最后位置
* 此方法对于某些无序集合的位置信息,以转换为数组后的位置为准。 * * @param 元素类型 * @param collection 集合 * @param matcher 匹配器,为空则全部匹配 * @return 最后一个位置 * @since 5.6.6 */ public static int lastIndexOf(Collection collection, Matcher matcher) { if (collection instanceof List) { // List的查找最后一个有优化算法 return ListUtil.lastIndexOf((List) collection, matcher); } int matchIndex = -1; if (isNotEmpty(collection)) { int index = 0; for (T t : collection) { if (null == matcher || matcher.match(t)) { matchIndex = index; } index++; } } return matchIndex; } /** * 获取匹配规则定义中匹配到元素的所有位置
* 此方法对于某些无序集合的位置信息,以转换为数组后的位置为准。 * * @param 元素类型 * @param collection 集合 * @param matcher 匹配器,为空则全部匹配 * @return 位置数组 * @since 5.2.5 */ public static int[] indexOfAll(Collection collection, Matcher matcher) { final List indexList = new ArrayList<>(); if (null != collection) { int index = 0; for (T t : collection) { if (null == matcher || matcher.match(t)) { indexList.add(index); } index++; } } return Convert.convert(int[].class, indexList); } // ---------------------------------------------------------------------- isEmpty /** * 集合是否为空 * * @param collection 集合 * @return 是否为空 */ public static boolean isEmpty(Collection collection) { return collection == null || collection.isEmpty(); } /** * 如果给定集合为空,返回默认集合 * * @param 集合类型 * @param 集合元素类型 * @param collection 集合 * @param defaultCollection 默认数组 * @return 非空(empty)的原集合或默认集合 * @since 4.6.9 */ public static , E> T defaultIfEmpty(T collection, T defaultCollection) { return isEmpty(collection) ? defaultCollection : collection; } /** * 如果给定集合为空,返回默认集合 * * @param 集合类型 * @param 集合元素类型 * @param collection 集合 * @param supplier 默认值懒加载函数 * @return 非空(empty)的原集合或默认集合 * @since 5.7.15 */ public static , E> T defaultIfEmpty(T collection, Supplier supplier) { return isEmpty(collection) ? supplier.get() : collection; } /** * Iterable是否为空 * * @param iterable Iterable对象 * @return 是否为空 * @see IterUtil#isEmpty(Iterable) */ public static boolean isEmpty(Iterable iterable) { return IterUtil.isEmpty(iterable); } /** * Iterator是否为空 * * @param Iterator Iterator对象 * @return 是否为空 * @see IterUtil#isEmpty(Iterator) */ public static boolean isEmpty(Iterator Iterator) { return IterUtil.isEmpty(Iterator); } /** * Enumeration是否为空 * * @param enumeration {@link Enumeration} * @return 是否为空 */ public static boolean isEmpty(Enumeration enumeration) { return null == enumeration || false == enumeration.hasMoreElements(); } /** * Map是否为空 * * @param map 集合 * @return 是否为空 * @see MapUtil#isEmpty(Map) * @since 5.7.4 */ public static boolean isEmpty(Map map) { return MapUtil.isEmpty(map); } // ---------------------------------------------------------------------- isNotEmpty /** * 集合是否为非空 * * @param collection 集合 * @return 是否为非空 */ public static boolean isNotEmpty(Collection collection) { return !isEmpty(collection); } /** * Iterable是否为空 * * @param iterable Iterable对象 * @return 是否为空 * @see IterUtil#isNotEmpty(Iterable) */ public static boolean isNotEmpty(Iterable iterable) { return IterUtil.isNotEmpty(iterable); } /** * Iterator是否为空 * * @param Iterator Iterator对象 * @return 是否为空 * @see IterUtil#isNotEmpty(Iterator) */ public static boolean isNotEmpty(Iterator Iterator) { return IterUtil.isNotEmpty(Iterator); } /** * Enumeration是否为空 * * @param enumeration {@link Enumeration} * @return 是否为空 */ public static boolean isNotEmpty(Enumeration enumeration) { return null != enumeration && enumeration.hasMoreElements(); } /** * 是否包含{@code null}元素 * * @param iterable 被检查的Iterable对象,如果为{@code null} 返回true * @return 是否包含{@code null}元素 * @see IterUtil#hasNull(Iterable) * @since 3.0.7 */ public static boolean hasNull(Iterable iterable) { return IterUtil.hasNull(iterable); } /** * Map是否为非空 * * @param map 集合 * @return 是否为非空 * @see MapUtil#isNotEmpty(Map) * @since 5.7.4 */ public static boolean isNotEmpty(Map map) { return MapUtil.isNotEmpty(map); } // ---------------------------------------------------------------------- zip /** * 映射键值(参考Python的zip()函数)
* 例如:
* keys = a,b,c,d
* values = 1,2,3,4
* delimiter = , 则得到的Map是 {a=1, b=2, c=3, d=4}
* 如果两个数组长度不同,则只对应最短部分 * * @param keys 键列表 * @param values 值列表 * @param delimiter 分隔符 * @param isOrder 是否有序 * @return Map * @since 3.0.4 */ public static Map zip(String keys, String values, String delimiter, boolean isOrder) { return ArrayUtil.zip(StrUtil.splitToArray(keys, delimiter), StrUtil.splitToArray(values, delimiter), isOrder); } /** * 映射键值(参考Python的zip()函数),返回Map无序
* 例如:
* keys = a,b,c,d
* values = 1,2,3,4
* delimiter = , 则得到的Map是 {a=1, b=2, c=3, d=4}
* 如果两个数组长度不同,则只对应最短部分 * * @param keys 键列表 * @param values 值列表 * @param delimiter 分隔符 * @return Map */ public static Map zip(String keys, String values, String delimiter) { return zip(keys, values, delimiter, false); } /** * 映射键值(参考Python的zip()函数)
* 例如:
* keys = [a,b,c,d]
* values = [1,2,3,4]
* 则得到的Map是 {a=1, b=2, c=3, d=4}
* 如果两个数组长度不同,则只对应最短部分 * * @param 键类型 * @param 值类型 * @param keys 键列表 * @param values 值列表 * @return Map */ public static Map zip(Collection keys, Collection values) { if (isEmpty(keys) || isEmpty(values)) { return MapUtil.empty(); } int entryCount = Math.min(keys.size(), values.size()); final Map map = MapUtil.newHashMap(entryCount); final Iterator keyIterator = keys.iterator(); final Iterator valueIterator = values.iterator(); while (entryCount > 0) { map.put(keyIterator.next(), valueIterator.next()); entryCount--; } return map; } /** * 将Entry集合转换为HashMap * * @param 键类型 * @param 值类型 * @param entryIter entry集合 * @return Map * @see IterUtil#toMap(Iterable) */ public static HashMap toMap(Iterable> entryIter) { return IterUtil.toMap(entryIter); } /** * 将数组转换为Map(HashMap),支持数组元素类型为: * *
	 * Map.Entry
	 * 长度大于1的数组(取前两个值),如果不满足跳过此元素
	 * Iterable 长度也必须大于1(取前两个值),如果不满足跳过此元素
	 * Iterator 长度也必须大于1(取前两个值),如果不满足跳过此元素
	 * 
* *
	 * Map<Object, Object> colorMap = CollectionUtil.toMap(new String[][] {{
	 *     {"RED", "#FF0000"},
	 *     {"GREEN", "#00FF00"},
	 *     {"BLUE", "#0000FF"}});
	 * 
*

* 参考:commons-lang * * @param array 数组。元素类型为Map.Entry、数组、Iterable、Iterator * @return {@link HashMap} * @see MapUtil#of(Object[]) * @since 3.0.8 */ public static HashMap toMap(Object[] array) { return MapUtil.of(array); } /** * 将集合转换为排序后的TreeSet * * @param 集合元素类型 * @param collection 集合 * @param comparator 比较器 * @return treeSet */ public static TreeSet toTreeSet(Collection collection, Comparator comparator) { final TreeSet treeSet = new TreeSet<>(comparator); treeSet.addAll(collection); return treeSet; } /** * Iterator转换为Enumeration *

* Adapt the specified {@link Iterator} to the {@link Enumeration} interface. * * @param 集合元素类型 * @param iter {@link Iterator} * @return {@link Enumeration} */ public static Enumeration asEnumeration(Iterator iter) { return new IteratorEnumeration<>(iter); } /** * Enumeration转换为Iterator *

* Adapt the specified {@code Enumeration} to the {@code Iterator} interface * * @param 集合元素类型 * @param e {@link Enumeration} * @return {@link Iterator} * @see IterUtil#asIterator(Enumeration) */ public static Iterator asIterator(Enumeration e) { return IterUtil.asIterator(e); } /** * {@link Iterator} 转为 {@link Iterable} * * @param 元素类型 * @param iter {@link Iterator} * @return {@link Iterable} * @see IterUtil#asIterable(Iterator) */ public static Iterable asIterable(final Iterator iter) { return IterUtil.asIterable(iter); } /** * {@link Iterable}转为{@link Collection}
* 首先尝试强转,强转失败则构建一个新的{@link ArrayList} * * @param 集合元素类型 * @param iterable {@link Iterable} * @return {@link Collection} 或者 {@link ArrayList} * @since 3.0.9 */ public static Collection toCollection(Iterable iterable) { return (iterable instanceof Collection) ? (Collection) iterable : newArrayList(iterable.iterator()); } /** * 行转列,合并相同的键,值合并为列表
* 将Map列表中相同key的值组成列表做为Map的value
* 是{@link #toMapList(Map)}的逆方法
* 比如传入数据: * *

	 * [
	 *  {a: 1, b: 1, c: 1}
	 *  {a: 2, b: 2}
	 *  {a: 3, b: 3}
	 *  {a: 4}
	 * ]
	 * 
*

* 结果是: * *

	 * {
	 *   a: [1,2,3,4]
	 *   b: [1,2,3,]
	 *   c: [1]
	 * }
	 * 
* * @param 键类型 * @param 值类型 * @param mapList Map列表 * @return Map * @see MapUtil#toListMap(Iterable) */ public static Map> toListMap(Iterable> mapList) { return MapUtil.toListMap(mapList); } /** * 列转行。将Map中值列表分别按照其位置与key组成新的map。
* 是{@link #toListMap(Iterable)}的逆方法
* 比如传入数据: * *
	 * {
	 *   a: [1,2,3,4]
	 *   b: [1,2,3,]
	 *   c: [1]
	 * }
	 * 
*

* 结果是: * *

	 * [
	 *  {a: 1, b: 1, c: 1}
	 *  {a: 2, b: 2}
	 *  {a: 3, b: 3}
	 *  {a: 4}
	 * ]
	 * 
* * @param 键类型 * @param 值类型 * @param listMap 列表Map * @return Map列表 * @see MapUtil#toMapList(Map) */ public static List> toMapList(Map> listMap) { return MapUtil.toMapList(listMap); } /** * 集合转换为Map,转换规则为:
* 按照keyFunc函数规则根据元素对象生成Key,元素作为值 * * @param Map键类型 * @param Map值类型 * @param values 数据列表 * @param map Map对象,转换后的键值对加入此Map,通过传入此对象自定义Map类型 * @param keyFunc 生成key的函数 * @return 生成的map * @since 5.2.6 */ public static Map toMap(Iterable values, Map map, Func1 keyFunc) { return IterUtil.toMap(null == values ? null : values.iterator(), map, keyFunc); } /** * 集合转换为Map,转换规则为:
* 按照keyFunc函数规则根据元素对象生成Key,按照valueFunc函数规则根据元素对象生成value组成新的Map * * @param Map键类型 * @param Map值类型 * @param 元素类型 * @param values 数据列表 * @param map Map对象,转换后的键值对加入此Map,通过传入此对象自定义Map类型 * @param keyFunc 生成key的函数 * @param valueFunc 生成值的策略函数 * @return 生成的map * @since 5.2.6 */ public static Map toMap(Iterable values, Map map, Func1 keyFunc, Func1 valueFunc) { return IterUtil.toMap(null == values ? null : values.iterator(), map, keyFunc, valueFunc); } /** * 一个对象不为空且不存在于该集合中时,加入到该集合中
*
	 *     null, null -> false
	 *     [], null -> false
	 *     null, "123" -> false
	 *     ["123"], "123" -> false
	 *     [], "123" -> true
	 *     ["456"], "123" -> true
	 *     [Animal{"name": "jack"}], Dog{"name": "jack"} -> true
	 * 
* * @param collection 被加入的集合 * @param object 要添加到集合的对象 * @param 集合元素类型 * @param 要添加的元素类型【为集合元素类型的类型或子类型】 * @return 是否添加成功 * @author Cloud-Style */ public static boolean addIfAbsent(Collection collection, S object) { if (object == null || collection == null || collection.contains(object)) { return false; } return collection.add(object); } /** * 将指定对象全部加入到集合中
* 提供的对象如果为集合类型,会自动转换为目标元素类型
* * @param 元素类型 * @param collection 被加入的集合 * @param value 对象,可能为Iterator、Iterable、Enumeration、Array * @return 被加入集合 */ public static Collection addAll(Collection collection, Object value) { return addAll(collection, value, TypeUtil.getTypeArgument(collection.getClass())); } /** * 将指定对象全部加入到集合中
* 提供的对象如果为集合类型,会自动转换为目标元素类型
* 如果为String,支持类似于[1,2,3,4] 或者 1,2,3,4 这种格式 * * @param 元素类型 * @param collection 被加入的集合 * @param value 对象,可能为Iterator、Iterable、Enumeration、Array,或者与集合元素类型一致 * @param elementType 元素类型,为空时,使用Object类型来接纳所有类型 * @return 被加入集合 */ @SuppressWarnings({"unchecked", "rawtypes"}) public static Collection addAll(Collection collection, Object value, Type elementType) { if (null == collection || null == value) { return collection; } if (TypeUtil.isUnknown(elementType)) { // 元素类型为空时,使用Object类型来接纳所有类型 elementType = Object.class; } Iterator iter; if (value instanceof Iterator) { iter = (Iterator) value; } else if (value instanceof Iterable) { if(value instanceof Map && BeanUtil.isBean(TypeUtil.getClass(elementType))){ //https://github.com/dromara/hutool/issues/3139 // 如果值为Map,而目标为一个Bean,则Map应整体转换为Bean,而非拆分成Entry转换 iter = new ArrayIter<>(new Object[]{value}); }else{ iter = ((Iterable) value).iterator(); } } else if (value instanceof Enumeration) { iter = new EnumerationIter<>((Enumeration) value); } else if (ArrayUtil.isArray(value)) { iter = new ArrayIter<>(value); } else if (value instanceof CharSequence) { // String按照逗号分隔的列表对待 final String ArrayStr = StrUtil.unWrap((CharSequence) value, '[', ']'); iter = StrUtil.splitTrim(ArrayStr, CharUtil.COMMA).iterator(); } else { // 其它类型按照单一元素处理 iter = CollUtil.newArrayList(value).iterator(); } final ConverterRegistry convert = ConverterRegistry.getInstance(); while (iter.hasNext()) { collection.add(convert.convert(elementType, iter.next())); } return collection; } /** * 加入全部 * * @param 集合元素类型 * @param collection 被加入的集合 {@link Collection} * @param iterator 要加入的{@link Iterator} * @return 原集合 */ public static Collection addAll(Collection collection, Iterator iterator) { if (null != collection && null != iterator) { while (iterator.hasNext()) { collection.add(iterator.next()); } } return collection; } /** * 加入全部 * * @param 集合元素类型 * @param collection 被加入的集合 {@link Collection} * @param iterable 要加入的内容{@link Iterable} * @return 原集合 */ public static Collection addAll(Collection collection, Iterable iterable) { if (iterable == null) { return collection; } return addAll(collection, iterable.iterator()); } /** * 加入全部 * * @param 集合元素类型 * @param collection 被加入的集合 {@link Collection} * @param enumeration 要加入的内容{@link Enumeration} * @return 原集合 */ public static Collection addAll(Collection collection, Enumeration enumeration) { if (null != collection && null != enumeration) { while (enumeration.hasMoreElements()) { collection.add(enumeration.nextElement()); } } return collection; } /** * 加入全部 * * @param 集合元素类型 * @param collection 被加入的集合 {@link Collection} * @param values 要加入的内容数组 * @return 原集合 * @since 3.0.8 */ public static Collection addAll(Collection collection, T[] values) { if (null != collection && null != values) { Collections.addAll(collection, values); } return collection; } /** * 将另一个列表中的元素加入到列表中,如果列表中已经存在此元素则忽略之 * * @param 集合元素类型 * @param list 列表 * @param otherList 其它列表 * @return 此列表 */ public static List addAllIfNotContains(List list, List otherList) { for (T t : otherList) { if (false == list.contains(t)) { list.add(t); } } return list; } /** * 获取集合中指定下标的元素值,下标可以为负数,例如-1表示最后一个元素
* 如果元素越界,返回null * * @param 元素类型 * @param collection 集合 * @param index 下标,支持负数 * @return 元素值 * @since 4.0.6 */ public static T get(Collection collection, int index) { if (null == collection) { return null; } final int size = collection.size(); if (0 == size) { return null; } if (index < 0) { index += size; } // 检查越界 if (index >= size || index < 0) { return null; } if (collection instanceof List) { final List list = ((List) collection); return list.get(index); } else { return IterUtil.get(collection.iterator(), index); } } /** * 获取集合中指定多个下标的元素值,下标可以为负数,例如-1表示最后一个元素 * * @param 元素类型 * @param collection 集合 * @param indexes 下标,支持负数 * @return 元素值列表 * @since 4.0.6 */ @SuppressWarnings("unchecked") public static List getAny(Collection collection, int... indexes) { final int size = collection.size(); final ArrayList result = new ArrayList<>(); if (collection instanceof List) { final List list = ((List) collection); for (int index : indexes) { if (index < 0) { index += size; } result.add(list.get(index)); } } else { final Object[] array = collection.toArray(); for (int index : indexes) { if (index < 0) { index += size; } result.add((T) array[index]); } } return result; } /** * 获取集合的第一个元素 * * @param 集合元素类型 * @param iterable {@link Iterable} * @return 第一个元素 * @see IterUtil#getFirst(Iterable) * @since 3.0.1 */ public static T getFirst(Iterable iterable) { return IterUtil.getFirst(iterable); } /** * 获取集合的第一个元素 * * @param 集合元素类型 * @param iterator {@link Iterator} * @return 第一个元素 * @see IterUtil#getFirst(Iterator) * @since 3.0.1 */ public static T getFirst(Iterator iterator) { return IterUtil.getFirst(iterator); } /** * 获取集合的最后一个元素 * * @param 集合元素类型 * @param collection {@link Collection} * @return 最后一个元素 * @since 4.1.10 */ public static T getLast(Collection collection) { return get(collection, -1); } /** * 获得{@link Iterable}对象的元素类型(通过第一个非空元素判断) * * @param iterable {@link Iterable} * @return 元素类型,当列表为空或元素全部为null时,返回null * @see IterUtil#getElementType(Iterable) * @since 3.0.8 * @deprecated 请使用 {@link IterUtil#getElementType(Iterable)} */ @Deprecated public static Class getElementType(Iterable iterable) { return IterUtil.getElementType(iterable); } /** * 获得{@link Iterator}对象的元素类型(通过第一个非空元素判断) * * @param iterator {@link Iterator} * @return 元素类型,当列表为空或元素全部为null时,返回null * @see IterUtil#getElementType(Iterator) * @since 3.0.8 * @deprecated 请使用 {@link IterUtil#getElementType(Iterator)} */ @Deprecated public static Class getElementType(Iterator iterator) { return IterUtil.getElementType(iterator); } /** * 从Map中获取指定键列表对应的值列表
* 如果key在map中不存在或key对应值为null,则返回值列表对应位置的值也为null * * @param 键类型 * @param 值类型 * @param map {@link Map} * @param keys 键列表 * @return 值列表 * @since 3.0.8 */ @SuppressWarnings("unchecked") public static ArrayList valuesOfKeys(Map map, K... keys) { return MapUtil.valuesOfKeys(map, new ArrayIter<>(keys)); } /** * 从Map中获取指定键列表对应的值列表
* 如果key在map中不存在或key对应值为null,则返回值列表对应位置的值也为null * * @param 键类型 * @param 值类型 * @param map {@link Map} * @param keys 键列表 * @return 值列表 * @since 3.0.9 */ public static ArrayList valuesOfKeys(Map map, Iterable keys) { return valuesOfKeys(map, keys.iterator()); } /** * 从Map中获取指定键列表对应的值列表
* 如果key在map中不存在或key对应值为null,则返回值列表对应位置的值也为null * * @param 键类型 * @param 值类型 * @param map {@link Map} * @param keys 键列表 * @return 值列表 * @since 3.0.9 */ public static ArrayList valuesOfKeys(Map map, Iterator keys) { return MapUtil.valuesOfKeys(map, keys); } // ------------------------------------------------------------------------------------------------- sort /** * 将多个集合排序并显示不同的段落(分页)
* 采用{@link BoundedPriorityQueue}实现分页取局部 * * @param 集合元素类型 * @param pageNo 页码,从0开始计数,0表示第一页 * @param pageSize 每页的条目数 * @param comparator 比较器 * @param colls 集合数组 * @return 分页后的段落内容 */ @SafeVarargs public static List sortPageAll(int pageNo, int pageSize, Comparator comparator, Collection... colls) { final List list = new ArrayList<>(pageNo * pageSize); for (Collection coll : colls) { list.addAll(coll); } if (null != comparator) { list.sort(comparator); } return page(pageNo, pageSize, list); } /** * 对指定List分页取值 * * @param 集合元素类型 * @param pageNo 页码,从0开始计数,0表示第一页 * @param pageSize 每页的条目数 * @param list 列表 * @return 分页后的段落内容 * @since 4.1.20 */ public static List page(int pageNo, int pageSize, List list) { return ListUtil.page(pageNo, pageSize, list); } /** * 排序集合,排序不会修改原集合 * * @param 集合元素类型 * @param collection 集合 * @param comparator 比较器 * @return treeSet */ public static List sort(Collection collection, Comparator comparator) { List list = new ArrayList<>(collection); list.sort(comparator); return list; } /** * 针对List排序,排序会修改原List * * @param 元素类型 * @param list 被排序的List * @param c {@link Comparator} * @return 原list * @see Collections#sort(List, Comparator) */ public static List sort(List list, Comparator c) { return ListUtil.sort(list, c); } /** * 根据Bean的属性排序 * * @param 元素类型 * @param collection 集合,会被转换为List * @param property 属性名 * @return 排序后的List * @since 4.0.6 */ public static List sortByProperty(Collection collection, String property) { return sort(collection, new PropertyComparator<>(property)); } /** * 根据Bean的属性排序 * * @param 元素类型 * @param list List * @param property 属性名 * @return 排序后的List * @since 4.0.6 */ public static List sortByProperty(List list, String property) { return ListUtil.sortByProperty(list, property); } /** * 根据汉字的拼音顺序排序 * * @param collection 集合,会被转换为List * @return 排序后的List * @since 4.0.8 */ public static List sortByPinyin(Collection collection) { return sort(collection, new PinyinComparator()); } /** * 根据汉字的拼音顺序排序 * * @param list List * @return 排序后的List * @since 4.0.8 */ public static List sortByPinyin(List list) { return ListUtil.sortByPinyin(list); } /** * 排序Map * * @param 键类型 * @param 值类型 * @param map Map * @param comparator Entry比较器 * @return {@link TreeMap} * @since 3.0.9 */ public static TreeMap sort(Map map, Comparator comparator) { final TreeMap result = new TreeMap<>(comparator); result.putAll(map); return result; } /** * 通过Entry排序,可以按照键排序,也可以按照值排序,亦或者两者综合排序 * * @param 键类型 * @param 值类型 * @param entryCollection Entry集合 * @param comparator {@link Comparator} * @return {@link LinkedList} * @since 3.0.9 */ public static LinkedHashMap sortToMap(Collection> entryCollection, Comparator> comparator) { List> list = new LinkedList<>(entryCollection); list.sort(comparator); LinkedHashMap result = new LinkedHashMap<>(); for (Map.Entry entry : list) { result.put(entry.getKey(), entry.getValue()); } return result; } /** * 通过Entry排序,可以按照键排序,也可以按照值排序,亦或者两者综合排序 * * @param 键类型 * @param 值类型 * @param map 被排序的Map * @param comparator {@link Comparator} * @return {@link LinkedList} * @since 3.0.9 */ public static LinkedHashMap sortByEntry(Map map, Comparator> comparator) { return sortToMap(map.entrySet(), comparator); } /** * 将Set排序(根据Entry的值) * * @param 键类型 * @param 值类型 * @param collection 被排序的{@link Collection} * @return 排序后的Set */ @SuppressWarnings({"unchecked", "rawtypes"}) public static List> sortEntryToList(Collection> collection) { List> list = new LinkedList<>(collection); list.sort((o1, o2) -> { V v1 = o1.getValue(); V v2 = o2.getValue(); if (v1 instanceof Comparable) { return ((Comparable) v1).compareTo(v2); } else { return v1.toString().compareTo(v2.toString()); } }); return list; } // ------------------------------------------------------------------------------------------------- forEach /** * 循环遍历 {@link Iterable},使用{@link Consumer} 接受遍历的每条数据,并针对每条数据做处理 * * @param 集合元素类型 * @param iterable {@link Iterable} * @param consumer {@link Consumer} 遍历的每条数据处理器 * @since 5.4.7 */ public static void forEach(Iterable iterable, Consumer consumer) { if (iterable == null) { return; } forEach(iterable.iterator(), consumer); } /** * 循环遍历 {@link Iterator},使用{@link Consumer} 接受遍历的每条数据,并针对每条数据做处理 * * @param 集合元素类型 * @param iterator {@link Iterator} * @param consumer {@link Consumer} 遍历的每条数据处理器 */ public static void forEach(Iterator iterator, Consumer consumer) { if (iterator == null) { return; } int index = 0; while (iterator.hasNext()) { consumer.accept(iterator.next(), index); index++; } } /** * 循环遍历 {@link Enumeration},使用{@link Consumer} 接受遍历的每条数据,并针对每条数据做处理 * * @param 集合元素类型 * @param enumeration {@link Enumeration} * @param consumer {@link Consumer} 遍历的每条数据处理器 */ public static void forEach(Enumeration enumeration, Consumer consumer) { if (enumeration == null) { return; } int index = 0; while (enumeration.hasMoreElements()) { consumer.accept(enumeration.nextElement(), index); index++; } } /** * 循环遍历Map,使用{@link KVConsumer} 接受遍历的每条数据,并针对每条数据做处理
* 和JDK8中的map.forEach不同的是,此方法支持index * * @param Key类型 * @param Value类型 * @param map {@link Map} * @param kvConsumer {@link KVConsumer} 遍历的每条数据处理器 */ public static void forEach(Map map, KVConsumer kvConsumer) { if (map == null) { return; } int index = 0; for (Entry entry : map.entrySet()) { kvConsumer.accept(entry.getKey(), entry.getValue(), index); index++; } } /** * 分组,按照{@link Hash32}接口定义的hash算法,集合中的元素放入hash值对应的子列表中 * * @param 元素类型 * @param collection 被分组的集合 * @param hash Hash值算法,决定元素放在第几个分组的规则 * @return 分组后的集合 */ public static List> group(Collection collection, Hash32 hash) { final List> result = new ArrayList<>(); if (isEmpty(collection)) { return result; } if (null == hash) { // 默认hash算法,按照元素的hashCode分组 hash = t -> (null == t) ? 0 : t.hashCode(); } int index; List subList; for (T t : collection) { index = hash.hash32(t); if (result.size() - 1 < index) { while (result.size() - 1 < index) { result.add(null); } result.set(index, newArrayList(t)); } else { subList = result.get(index); if (null == subList) { result.set(index, newArrayList(t)); } else { subList.add(t); } } } return result; } /** * 根据元素的指定字段名分组,非Bean都放在第一个分组中 * * @param 元素类型 * @param collection 集合 * @param fieldName 元素Bean中的字段名,非Bean都放在第一个分组中 * @return 分组列表 */ public static List> groupByField(Collection collection, final String fieldName) { return group(collection, new Hash32() { private final List fieldNameList = new ArrayList<>(); @Override public int hash32(T t) { if (null == t || false == BeanUtil.isBean(t.getClass())) { // 非Bean放在同一子分组中 return 0; } final Object value = ReflectUtil.getFieldValue(t, fieldName); int hash = fieldNameList.indexOf(value); if (hash < 0) { fieldNameList.add(value); return fieldNameList.size() - 1; } else { return hash; } } }); } /** * 反序给定List,会在原List基础上直接修改 * * @param 元素类型 * @param list 被反转的List * @return 反转后的List * @since 4.0.6 */ public static List reverse(List list) { return ListUtil.reverse(list); } /** * 反序给定List,会创建一个新的List,原List数据不变 * * @param 元素类型 * @param list 被反转的List * @return 反转后的List * @since 4.0.6 */ public static List reverseNew(List list) { return ListUtil.reverseNew(list); } /** * 设置或增加元素。当index小于List的长度时,替换指定位置的值,否则在尾部追加 * * @param 元素类型 * @param list List列表 * @param index 位置 * @param element 新元素 * @return 原List * @since 4.1.2 */ public static List setOrAppend(List list, int index, T element) { return ListUtil.setOrAppend(list, index, element); } /** * 获取指定Map列表中所有的Key * * @param 键类型 * @param mapCollection Map列表 * @return key集合 * @since 4.5.12 */ public static Set keySet(Collection> mapCollection) { if (isEmpty(mapCollection)) { return new HashSet<>(); } final HashSet set = new HashSet<>(mapCollection.size() * 16); for (Map map : mapCollection) { set.addAll(map.keySet()); } return set; } /** * 获取指定Map列表中所有的Value * * @param 值类型 * @param mapCollection Map列表 * @return Value集合 * @since 4.5.12 */ public static List values(Collection> mapCollection) { final List values = new ArrayList<>(); for (Map map : mapCollection) { values.addAll(map.values()); } return values; } /** * 取最大值 * * @param 元素类型 * @param coll 集合 * @return 最大值 * @see Collections#max(Collection) * @since 4.6.5 */ public static > T max(Collection coll) { return isEmpty(coll) ? null : Collections.max(coll); } /** * 取最小值 * * @param 元素类型 * @param coll 集合 * @return 最小值 * @see Collections#min(Collection) * @since 4.6.5 */ public static > T min(Collection coll) { return isEmpty(coll) ? null : Collections.min(coll); } /** * 转为只读集合 * * @param 元素类型 * @param c 集合 * @return 只读集合 * @since 5.2.6 */ public static Collection unmodifiable(Collection c) { return Collections.unmodifiableCollection(c); } /** * 根据给定的集合类型,返回对应的空集合,支持类型包括: * * *
	 *     1. NavigableSet
	 *     2. SortedSet
	 *     3. Set
	 *     4. List
	 * 
* * @param 元素类型 * @param 集合类型 * @param collectionClass 集合类型 * @return 空集合 * @since 5.3.1 */ @SuppressWarnings("unchecked") public static > T empty(Class collectionClass) { if (null == collectionClass) { return (T) Collections.emptyList(); } if (Set.class.isAssignableFrom(collectionClass)) { if (NavigableSet.class == collectionClass) { return (T) Collections.emptyNavigableSet(); } else if (SortedSet.class == collectionClass) { return (T) Collections.emptySortedSet(); } else { return (T) Collections.emptySet(); } } else if (List.class.isAssignableFrom(collectionClass)) { return (T) Collections.emptyList(); } // 不支持空集合的集合类型 throw new IllegalArgumentException(StrUtil.format("[{}] is not support to get empty!", collectionClass)); } /** * 清除一个或多个集合内的元素,每个集合调用clear()方法 * * @param collections 一个或多个集合 * @since 5.3.6 */ public static void clear(Collection... collections) { for (Collection collection : collections) { if (isNotEmpty(collection)) { collection.clear(); } } } /** * 填充List,以达到最小长度 * * @param 集合元素类型 * @param list 列表 * @param minLen 最小长度 * @param padObj 填充的对象 * @since 5.3.10 */ public static void padLeft(List list, int minLen, T padObj) { Objects.requireNonNull(list); if (list.isEmpty()) { padRight(list, minLen, padObj); return; } for (int i = list.size(); i < minLen; i++) { list.add(0, padObj); } } /** * 填充List,以达到最小长度 * * @param 集合元素类型 * @param list 列表 * @param minLen 最小长度 * @param padObj 填充的对象 * @since 5.3.10 */ public static void padRight(Collection list, int minLen, T padObj) { Objects.requireNonNull(list); for (int i = list.size(); i < minLen; i++) { list.add(padObj); } } /** * 使用给定的转换函数,转换源集合为新类型的集合 * * @param 源元素类型 * @param 目标元素类型 * @param collection 集合 * @param function 转换函数 * @return 新类型的集合 * @since 5.4.3 */ public static Collection trans(Collection collection, Function function) { return new TransCollection<>(collection, function); } /** * 使用给定的map将集合中的原素进行属性或者值的重新设定 * * @param 元素类型 * @param 替换的键 * @param 替换的值 * @param iterable 集合 * @param map 映射集 * @param keyGenerate 映射键生成函数 * @param biConsumer 封装映射到的值函数 * @author nick_wys * @since 5.7.18 */ public static void setValueByMap(Iterable iterable, Map map, Function keyGenerate, BiConsumer biConsumer) { iterable.forEach(x -> Optional.ofNullable(map.get(keyGenerate.apply(x))).ifPresent(y -> biConsumer.accept(x, y))); } // ---------------------------------------------------------------------------------------------- Interface start /** * 针对一个参数做相应的操作
* 此函数接口与JDK8中Consumer不同是多提供了index参数,用于标记遍历对象是第几个。 * * @param 处理参数类型 * @author Looly */ @FunctionalInterface public interface Consumer extends Serializable { /** * 接受并处理一个参数 * * @param value 参数值 * @param index 参数在集合中的索引 */ void accept(T value, int index); } /** * 针对两个参数做相应的操作,例如Map中的KEY和VALUE * * @param KEY类型 * @param VALUE类型 * @author Looly */ @FunctionalInterface public interface KVConsumer extends Serializable { /** * 接受并处理一对参数 * * @param key 键 * @param value 值 * @param index 参数在集合中的索引 */ void accept(K key, V value, int index); } // ---------------------------------------------------------------------------------------------- Interface end /** * 获取Collection或者iterator的大小,此方法可以处理的对象类型如下: *
    *
  • Collection - the collection size *
  • Map - the map size *
  • Array - the array size *
  • Iterator - the number of elements remaining in the iterator *
  • Enumeration - the number of elements remaining in the enumeration *
* * @param object 可以为空的对象 * @return 如果object为空则返回0 * @throws IllegalArgumentException 参数object不是Collection或者iterator * @since 5.5.0 */ public static int size(final Object object) { if (object == null) { return 0; } int total = 0; if (object instanceof Map) { total = ((Map) object).size(); } else if (object instanceof Collection) { total = ((Collection) object).size(); } else if (object instanceof Iterable) { total = IterUtil.size((Iterable) object); } else if (object instanceof Iterator) { total = IterUtil.size((Iterator) object); } else if (object instanceof Enumeration) { final Enumeration it = (Enumeration) object; while (it.hasMoreElements()) { total++; it.nextElement(); } } else if (ArrayUtil.isArray(object)) { total = ArrayUtil.length(object); } else { throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName()); } return total; } /** * 判断两个{@link Collection} 是否元素和顺序相同,返回{@code true}的条件是: *
    *
  • 两个{@link Collection}必须长度相同
  • *
  • 两个{@link Collection}元素相同index的对象必须equals,满足{@link Objects#equals(Object, Object)}
  • *
* 此方法来自Apache-Commons-Collections4。 * * @param list1 列表1 * @param list2 列表2 * @return 是否相同 * @since 5.6.0 */ public static boolean isEqualList(final Collection list1, final Collection list2) { if (list1 == list2) { return true; } if (list1 == null || list2 == null || list1.size() != list2.size()) { return false; } return IterUtil.isEqualList(list1, list2); } }