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

com.xiaoleilu.hutool.collection.CollUtil Maven / Gradle / Ivy

package com.xiaoleilu.hutool.collection;

import java.lang.reflect.Type;
import java.util.AbstractCollection;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Deque;
import java.util.EnumSet;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Stack;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.LinkedBlockingDeque;

import com.xiaoleilu.hutool.bean.BeanUtil;
import com.xiaoleilu.hutool.convert.Convert;
import com.xiaoleilu.hutool.convert.ConverterRegistry;
import com.xiaoleilu.hutool.exceptions.UtilException;
import com.xiaoleilu.hutool.lang.Editor;
import com.xiaoleilu.hutool.lang.Filter;
import com.xiaoleilu.hutool.lang.Matcher;
import com.xiaoleilu.hutool.map.MapUtil;
import com.xiaoleilu.hutool.util.ArrayUtil;
import com.xiaoleilu.hutool.util.ClassUtil;
import com.xiaoleilu.hutool.util.ObjectUtil;
import com.xiaoleilu.hutool.util.PageUtil;
import com.xiaoleilu.hutool.util.ReflectUtil;
import com.xiaoleilu.hutool.util.StrUtil;
import com.xiaoleilu.hutool.util.TypeUtil;

/**
 * 集合相关工具类,包括数组
 * 
 * @author xiaoleilu
 * @since 3.1.1
 */
public class CollUtil {

	/**
	 * 两个集合的并集
* 针对一个集合中存在多个相同元素的情况,计算两个集合中此元素的个数,保留最多的个数
* 例如:集合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(final Collection coll1, final Collection coll2) { final ArrayList list = new ArrayList<>(); if (isEmpty(coll1)) { list.addAll(coll2); } else if (isEmpty(coll2)) { list.addAll(coll1); } else { 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(final Collection coll1, final Collection coll2, final Collection... otherColls) { Collection union = union(coll1, coll2); for (Collection coll : otherColls) { union = union(union, coll); } return union; } /** * 两个集合的交集
* 针对一个集合中存在多个相同元素的情况,计算两个集合中此元素的个数,保留最少的个数
* 例如:集合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(final Collection coll1, final Collection coll2) { final ArrayList list = new ArrayList<>(); if (isNotEmpty(coll1) && isNotEmpty(coll2)) { 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; } /** * 多个集合的交集
* 针对一个集合中存在多个相同元素的情况,计算两个集合中此元素的个数,保留最少的个数
* 例如:集合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(final Collection coll1, final Collection coll2, final 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]
* 结果:[c],此结果中只保留了一个 * * @param 集合元素类型 * @param coll1 集合1 * @param coll2 集合2 * @return 差集的集合,返回 {@link ArrayList} */ public static Collection disjunction(final Collection coll1, final Collection coll2) { final ArrayList list = new ArrayList<>(); if (isNotEmpty(coll1) && isNotEmpty(coll2)) { 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++) { list.add(t); } } } return list; } /** * 其中一个集合在另一个集合中是否至少包含一个元素,既是两个集合是否至少有一个共同的元素 * * @param coll1 集合1 * @param coll2 集合2 * @return 其中一个集合在另一个集合中是否至少包含一个元素 * @since 2.1 * @see #intersection */ public static boolean containsAny(final Collection coll1, final 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; } /** * 根据集合返回一个元素计数的 {@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(Iterable) */ public static Map countMap(Iterable collection) { return IterUtil.countMap(collection); } /** * 以 conjunction 为分隔符将集合转换为字符串
* 如果集合元素为数组、{@link Iterable}或{@link Iterator},则递归组合其为字符串 * * @param 集合元素类型 * @param iterable {@link Iterable} * @param conjunction 分隔符 * @return 连接后的字符串 * @see IterUtil#join(Iterable, CharSequence) */ public static String join(Iterable iterable, CharSequence conjunction) { return IterUtil.join(iterable, conjunction); } /** * 以 conjunction 为分隔符将集合转换为字符串
* 如果集合元素为数组、{@link Iterable}或{@link Iterator},则递归组合其为字符串 * * @param 集合元素类型 * @param iterator 集合 * @param conjunction 分隔符 * @return 连接后的字符串 * @see IterUtil#join(Iterator, CharSequence) */ 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 null; } 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 null; } 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; } // ----------------------------------------------------------------------------------------------- new HashMap /** * 新建一个HashMap * * @param Key类型 * @param Value类型 * @return HashMap对象 * @see MapUtil#newHashMap() */ public static HashMap newHashMap() { return MapUtil.newHashMap(); } /** * 新建一个HashMap * * @param Key类型 * @param Value类型 * @param size 初始大小,由于默认负载因子0.75,传入的size会实际初始大小为size / 0.75 * @param isOrder Map的Key是否有序,有序返回 {@link LinkedHashMap},否则返回 {@link HashMap} * @return HashMap对象 * @since 3.0.4 * @see MapUtil#newHashMap(int, boolean) */ public static HashMap newHashMap(int size, boolean isOrder) { return MapUtil.newHashMap(size, isOrder); } /** * 新建一个HashMap * * @param Key类型 * @param Value类型 * @param size 初始大小,由于默认负载因子0.75,传入的size会实际初始大小为size / 0.75 * @return HashMap对象 * @see MapUtil#newHashMap(int) */ public static HashMap newHashMap(int size) { return MapUtil.newHashMap(size); } // ----------------------------------------------------------------------------------------------- new HashSet /** * 新建一个HashSet * * @param 集合元素类型 * @param ts 元素数组 * @return HashSet对象 */ @SafeVarargs public static HashSet newHashSet(T... ts) { return newHashSet(false, ts); } /** * 新建一个HashSet * * @param 集合元素类型 * @param isSorted 是否有序,有序返回 {@link LinkedHashSet},否则返回 {@link HashSet} * @param ts 元素数组 * @return HashSet对象 */ @SafeVarargs public static HashSet newHashSet(boolean isSorted, T... ts) { if (null == ts) { return isSorted ? new LinkedHashSet() : new HashSet(); } int initialCapacity = Math.max((int) (ts.length / .75f) + 1, 16); HashSet set = isSorted ? new LinkedHashSet(initialCapacity) : new HashSet(initialCapacity); for (T t : ts) { set.add(t); } 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 newHashSet(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 enumration {@link Enumeration} * @return HashSet对象 * @since 3.0.8 */ public static HashSet newHashSet(boolean isSorted, Enumeration enumration) { if (null == enumration) { return newHashSet(isSorted, (T[]) null); } final HashSet set = isSorted ? new LinkedHashSet() : new HashSet(); while (enumration.hasMoreElements()) { set.add(enumration.nextElement()); } return set; } // ----------------------------------------------------------------------------------------------- new ArrayList /** * 新建一个ArrayList * * @param 集合元素类型 * @param values 数组 * @return ArrayList对象 */ @SafeVarargs public static ArrayList newArrayList(T... values) { if (null == values) { return new ArrayList<>(); } ArrayList arrayList = new ArrayList(values.length); for (T t : values) { arrayList.add(t); } return arrayList; } /** * 新建一个ArrayList * * @param 集合元素类型 * @param collection 集合 * @return ArrayList对象 */ public static ArrayList newArrayList(Collection collection) { if (null == collection) { return new ArrayList<>(); } return new ArrayList(collection); } /** * 新建一个ArrayList
* 提供的参数为null时返回空{@link ArrayList} * * @param 集合元素类型 * @param iterable {@link Iterable} * @return ArrayList对象 * @since 3.1.0 */ public static ArrayList newArrayList(Iterable iterable) { return (null == iterable) ? new ArrayList() : newArrayList(iterable.iterator()); } /** * 新建一个ArrayList
* 提供的参数为null时返回空{@link ArrayList} * * @param 集合元素类型 * @param iter {@link Iterator} * @return ArrayList对象 * @since 3.0.8 */ public static ArrayList newArrayList(Iterator iter) { final ArrayList list = new ArrayList<>(); if (null == iter) { return list; } while (iter.hasNext()) { list.add(iter.next()); } return list; } /** * 新建一个ArrayList
* 提供的参数为null时返回空{@link ArrayList} * * @param 集合元素类型 * @param enumration {@link Enumeration} * @return ArrayList对象 * @since 3.0.8 */ public static ArrayList newArrayList(Enumeration enumration) { final ArrayList list = new ArrayList<>(); if (null == enumration) { return list; } while (enumration.hasMoreElements()) { list.add(enumration.nextElement()); } return list; } /** * 新建一个CopyOnWriteArrayList * * @param 集合元素类型 * @param collection 集合 * @return {@link CopyOnWriteArrayList} */ public static CopyOnWriteArrayList newCopyOnWriteArrayList(Collection collection) { return (null == collection) ? (new CopyOnWriteArrayList()) : (new CopyOnWriteArrayList(collection)); } /** * 新建{@link BlockingQueue}
* 在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。 * * @param capacity 容量 * @param isLinked 是否为链表形式 * @return {@link BlockingQueue} * @since 3.3.0 */ public static BlockingQueue newBlockingQueue(int capacity, boolean isLinked){ BlockingQueue queue; if(isLinked) { queue = new LinkedBlockingDeque<>(capacity); }else { queue = new ArrayBlockingQueue<>(capacity); } return queue; } /** * 创建新的集合对象 * * @param 集合类型 * @param collectionType 集合类型 * @return 集合类型对应的实例 * @since 3.0.8 */ @SuppressWarnings({ "unchecked", "rawtypes" }) public static Collection create(Class collectionType) { Collection list = null; 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<>(); } else if (collectionType.isAssignableFrom(EnumSet.class)) { list = (Collection) EnumSet.noneOf((Class) ClassUtil.getTypeArgument(collectionType)); } // 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 (Exception e) { throw new UtilException(e); } } return list; } /** * 创建Map
* 传入抽象Map{@link AbstractMap}和{@link Map}类将默认创建{@link HashMap} * * @param map键类型 * @param map值类型 * @param mapType map类型 * @return {@link Map}实例 * @see MapUtil#createMap(Class) */ public static Map createMap(Class mapType) { return MapUtil.createMap(mapType); } /** * 去重集合 * * @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)); } } /** * 截取集合的部分 * * @param 集合元素类型 * @param list 被截取的数组 * @param start 开始位置(包含) * @param end 结束位置(不包含) * @return 截取后的数组,当开始位置超过最大时,返回null */ public static List sub(List list, int start, int end) { if (list == null || list.isEmpty()) { return null; } if (start < 0) { start = 0; } if (end < 0) { end = 0; } if (start > end) { int tmp = start; start = end; end = tmp; } final int size = list.size(); if (end > size) { if (start >= size) { return null; } end = size; } return list.subList(start, end); } /** * 截取集合的部分 * * @param 集合元素类型 * @param list 被截取的数组 * @param start 开始位置(包含) * @param end 结束位置(不包含) * @return 截取后的数组,当开始位置超过最大时,返回null */ public static List sub(Collection list, int start, int end) { if (list == null || list.isEmpty()) { return null; } return sub(new ArrayList(list), start, end); } /** * 对集合按照指定长度分段,每一个段为单独的集合,返回这个集合的列表 * * @param 集合元素类型 * @param collection 集合 * @param size 每个段的长度 * @return 分段列表 */ public static List> split(Collection collection, int size) { final List> result = new ArrayList<>(); ArrayList subList = new ArrayList<>(size); for (T t : collection) { if (subList.size() >= size) { result.add(subList); subList = new ArrayList<>(size); } subList.add(t); } result.add(subList); return result; } /** * 过滤
* 过滤过程通过传入的Editor实现来返回需要的元素内容,这个Editor实现可以实现以下功能: * *
	 * 1、过滤出需要的对象,如果返回null表示这个元素对象抛弃
	 * 2、修改元素对象,返回集合中为修改后的对象
	 * 
* * @param 集合元素类型 * @param collection 集合 * @param editor 编辑器接口 * @return 过滤后的数组 */ public static Collection filter(Collection collection, Editor editor) { Collection collection2 = ObjectUtil.clone(collection); try { collection2.clear(); } catch (UnsupportedOperationException e) { //克隆后的对象不支持清空,说明为不可变集合对象,使用默认的ArrayList保存结果 collection2 = new ArrayList<>(); } T modified; for (T t : collection) { modified = editor.edit(t); if (null != modified) { collection2.add(modified); } } return collection2; } /** * 过滤
* 过滤过程通过传入的Filter实现来过滤返回需要的元素内容,这个Editor实现可以实现以下功能: * *
	 * 1、过滤出需要的对象,{@link Filter#accept(Object)}方法返回true的对象将被加入结果集合中
	 * 
* * @param 集合元素类型 * @param collection 集合 * @param filter 过滤器 * @return 过滤后的数组 * @since 3.1.0 */ public static Collection filter(Collection collection, Filter filter) { Collection collection2 = ObjectUtil.clone(collection); try { collection2.clear(); } catch (UnsupportedOperationException e) { //克隆后的对象不支持清空,说明为不可变集合对象,使用默认的ArrayList保存结果 collection2 = new ArrayList<>(); } for (T t : collection) { if (filter.accept(t)) { collection2.add(t); } } return collection2; } /** * 去除{@code null} 元素 * @param collection 集合 * @return 处理后的集合 * @since 3.2.2 */ public static Collection removeNull(Collection collection) { return filter(collection, new Editor() { @Override public T edit(T t) { //返回null便不加入集合 return t; }}); } /** * 去除{@code null}或者"" 元素 * @param collection 集合 * @return 处理后的集合 * @since 3.2.2 */ public static Collection removeEmpty(Collection collection) { return filter(collection, new Filter() { @Override public boolean accept(T t) { return false == StrUtil.isEmpty(t); }}); } /** * 去除{@code null}或者""或者空白字符串 元素 * @param collection 集合 * @return 处理后的集合 * @since 3.2.2 */ public static Collection removeBlank(Collection collection) { return filter(collection, new Filter() { @Override public boolean accept(T t) { return false == StrUtil.isBlank(t); }}); } /** * 通过Editor抽取集合元素中的某些值返回为新列表
* 例如提供的是一个Bean列表,通过Editor接口实现获取某个字段值,返回这个字段值组成的新列表 * * @param collection 原集合 * @param editor 编辑器 * @return 抽取后的新列表 */ public static List extract(Iterable collection, Editor editor) { final List fieldValueList = new ArrayList<>(); for (Object bean : collection) { fieldValueList.add(editor.edit(bean)); } 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 extract(collection, new Editor(){ @Override public Object edit(Object bean) { if (bean instanceof Map) { return ((Map) bean).get(fieldName); } else { return ReflectUtil.getFieldValue(bean, fieldName); } } }); } /** * 查找第一个匹配元素对象 * * @param 集合元素类型 * @param collection 集合 * @param filter 过滤器,满足过滤条件的第一个元素将被返回 * @return 满足过滤条件的第一个元素 * @since 3.1.0 */ public static T findOne(Iterable collection, Filter filter) { 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, new Filter(){ @Override public boolean accept(T 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); } }); } /** * 过滤
* 过滤过程通过传入的Editor实现来返回需要的元素内容,这个Editor实现可以实现以下功能: * *
	 * 1、过滤出需要的对象,如果返回null表示这个元素对象抛弃
	 * 2、修改元素对象,返回集合中为修改后的对象
	 * 
* * @param Key类型 * @param Value类型 * @param map Map * @param editor 编辑器接口 * @return 过滤后的Map * @see MapUtil#filter(Map, Editor) */ public static Map filter(Map map, Editor> editor) { return MapUtil.filter(map, editor); } /** * 过滤
* 过滤过程通过传入的Editor实现来返回需要的元素内容,这个Editor实现可以实现以下功能: * *
	 * 1、过滤出需要的对象,如果返回null表示这个元素对象抛弃
	 * 2、修改元素对象,返回集合中为修改后的对象
	 * 
* * @param Key类型 * @param Value类型 * @param map Map * @param filter 编辑器接口 * @return 过滤后的Map * @since 3.1.0 * @see MapUtil#filter(Map, Filter) */ public static Map filter(Map map, Filter> filter) { return MapUtil.filter(map, filter); } /** * 集合中匹配规则的数量 * * @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; } // ---------------------------------------------------------------------- isEmpty /** * 集合是否为空 * * @param collection 集合 * @return 是否为空 */ public static boolean isEmpty(Collection collection) { return collection == null || collection.isEmpty(); } /** * Map是否为空 * * @param map 集合 * @return 是否为空 * @see MapUtil#isEmpty(Map) */ public static boolean isEmpty(Map map) { return MapUtil.isEmpty(map); } /** * 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(); } // ---------------------------------------------------------------------- isNotEmpty /** * 集合是否为非空 * * @param collection 集合 * @return 是否为非空 */ public static boolean isNotEmpty(Collection collection) { return false == isEmpty(collection); } /** * Map是否为非空 * * @param map 集合 * @return 是否为非空 * @see MapUtil#isNotEmpty(Map) */ public static boolean isNotEmpty(Map map) { return MapUtil.isNotEmpty(map); } /** * 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} 返回false * @return 是否包含{@code null}元素 * @since 3.0.7 * @see IterUtil#hasNull(Iterable) */ public static boolean hasNull(Iterable iterable) { return IterUtil.hasNull(iterable); } // ---------------------------------------------------------------------- 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.split(keys, delimiter), StrUtil.split(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 null; } final List keyList = new ArrayList(keys); final List valueList = new ArrayList(values); final int size = Math.min(keys.size(), values.size()); final Map map = new HashMap((int) (size / 0.75)); for (int i = 0; i < size; i++) { map.put(keyList.get(i), valueList.get(i)); } 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} * @since 3.0.8 * @see MapUtil#of(Object[]) */ 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); for (T t : collection) { treeSet.add(t); } return treeSet; } /** * Iterator转换为Enumeration *

* Adapt the specified Iterator to the 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 Enumeration to the 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); } /** * 将指定对象全部加入到集合中
* 提供的对象如果为集合类型,会自动转换为目标元素类型
* * @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())); } /** * 将指定对象全部加入到集合中
* 提供的对象如果为集合类型,会自动转换为目标元素类型
* * @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 (null == elementType) { // 元素类型为空时,使用Object类型来接纳所有类型 elementType = Object.class; }else { final Class elementRowType = TypeUtil.getClass(elementType); if(elementRowType.isInstance(value) && false == Iterable.class.isAssignableFrom(elementRowType)) { //其它类型按照单一元素处理 collection.add((T) value); return collection; } } Iterator iter; if (value instanceof Iterator) { iter = (Iterator) value; } else if (value instanceof Iterable) { iter = ((Iterable) value).iterator(); } else if (value instanceof Enumeration) { iter = new EnumerationIterator<>((Enumeration) value); } else if (ArrayUtil.isArray(value)) { iter = new ArrayIterator<>(value); } else { throw new UtilException("Unsupport value type [] !", value.getClass()); } final ConverterRegistry convert = ConverterRegistry.getInstance(); while (iter.hasNext()) { try { collection.add((T) convert.convert(elementType, iter.next())); } catch (Exception e) { e.printStackTrace(); } } 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) { 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) { for (T value : values) { collection.add(value); } } 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; } /** * 获取集合的第一个元素 * * @param 集合元素类型 * @param iterable {@link Iterable} * @return 第一个元素 * @since 3.0.1 * @see IterUtil#getFirst(Iterable) */ public static T getFirst(Iterable iterable) { return IterUtil.getFirst(iterable); } /** * 获取集合的第一个元素 * * @param 集合元素类型 * @param iterator {@link Iterator} * @return 第一个元素 * @since 3.0.1 * @see IterUtil#getFirst(Iterator) */ public static T getFirst(Iterator iterator) { return IterUtil.getFirst(iterator); } /** * 获得{@link Iterable}对象的元素类型(通过第一个非空元素判断) * * @param iterable {@link Iterable} * @return 元素类型,当列表为空或元素全部为null时,返回null * @since 3.0.8 * @see IterUtil#getElementType(Iterable) */ public static Class getElementType(Iterable iterable) { return IterUtil.getElementType(iterable); } /** * 获得{@link Iterator}对象的元素类型(通过第一个非空元素判断) * * @param iterator {@link Iterator} * @return 元素类型,当列表为空或元素全部为null时,返回null * @since 3.0.8 * @see IterUtil#getElementType(Iterator) */ 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) { final ArrayList values = new ArrayList<>(); for (K k : keys) { values.add(map.get(k)); } return values; } /** * 从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) { final ArrayList values = new ArrayList<>(); while (keys.hasNext()) { values.add(map.get(keys.next())); } return values; } // ------------------------------------------------------------------------------------------------- sort /** * 将多个集合排序并显示不同的段落(分页)
* 采用先排序,后截断的方式取分页的部分 * * @param 集合元素类型 * @param pageNo 页码,从1开始 * @param numPerPage 每页的条目数 * @param comparator 比较器 * @param colls 集合数组 * @return 分页后的段落内容 */ @SafeVarargs public static List sortPageAll(int pageNo, int numPerPage, Comparator comparator, Collection... colls) { final List result = new ArrayList<>(); for (Collection coll : colls) { result.addAll(coll); } Collections.sort(result, comparator); int resultSize = result.size(); // 每页条目数大于总数直接返回所有 if (resultSize <= numPerPage) { return result; } final int[] startEnd = PageUtil.transToStartEnd(pageNo, numPerPage); if (startEnd[1] > resultSize) { // 越界直接返回空 return new ArrayList<>(); } return result.subList(startEnd[0], startEnd[1]); } /** * 将多个集合排序并显示不同的段落(分页)
* 采用{@link BoundedPriorityQueue}实现分页取局部 * * @param 集合元素类型 * @param pageNo 页码 * @param numPerPage 每页的条目数 * @param comparator 比较器 * @param colls 集合数组 * @return 分业后的段落内容 */ @SafeVarargs public static List sortPageAll2(int pageNo, int numPerPage, Comparator comparator, Collection... colls) { BoundedPriorityQueue queue = new BoundedPriorityQueue<>(pageNo * numPerPage, comparator); for (Collection coll : colls) { queue.addAll(coll); } int resultSize = queue.size(); // 每页条目数大于总数直接返回所有 if (resultSize <= numPerPage) { return queue.toList(); } final int[] startEnd = PageUtil.transToStartEnd(pageNo, numPerPage); if (startEnd[1] > resultSize) { // 越界直接返回空 return new ArrayList<>(); } return queue.toList().subList(startEnd[0], startEnd[1]); } /** * 排序集合,排序不会修改原集合 * * @param 集合元素类型 * @param collection 集合 * @param comparator 比较器 * @return treeSet */ public static List sort(Collection collection, Comparator comparator) { List list = new ArrayList(collection); Collections.sort(list, 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) { Collections.sort(list, c); return 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); Collections.sort(list, 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 */ public static List> sortEntryToList(Collection> collection) { List> list = new LinkedList<>(collection); Collections.sort(list, new Comparator>(){ @SuppressWarnings({ "rawtypes", "unchecked" }) @Override public int compare(Entry o1, Entry 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 Iterator},使用{@link Consumer} 接受遍历的每条数据,并针对每条数据做处理 * * @param 集合元素类型 * @param iterator {@link Iterator} * @param consumer {@link Consumer} 遍历的每条数据处理器 */ public static void forEach(Iterator iterator, Consumer consumer) { 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) { int index = 0; while (enumeration.hasMoreElements()) { consumer.accept(enumeration.nextElement(), index); index++; } } /** * 循环遍历Map,使用{@link KVConsumer} 接受遍历的每条数据,并针对每条数据做处理 * * @param Key类型 * @param Value类型 * @param map {@link Map} * @param kvConsumer {@link KVConsumer} 遍历的每条数据处理器 */ public static void forEach(Map map, KVConsumer kvConsumer) { int index = 0; for (Entry entry : map.entrySet()) { kvConsumer.accept(entry.getKey(), entry.getValue(), index); index++; } } /** * 分组,按照{@link Hash}接口定义的hash算法,集合中的元素放入hash值对应的子列表中 * * @param collection 被分组的集合 * @param hash Hash值算法,决定元素放在第几个分组的规则 * @return 分组后的集合 */ public static List> group(Collection collection, Hash hash){ final List> result = new ArrayList<>(); if(isEmpty(collection)) { return result; } if(null == hash) { //默认hash算法,按照元素的hashCode分组 hash = new Hash() { @Override public int hash(T t) { return null == t ? 0 : t.hashCode(); } }; } int index; List subList; for (T t : collection) { index = hash.hash(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 collection 集合 * @param fieldName 元素Bean中的字段名,非Bean都放在第一个分组中 * @return 分组列表 */ public static List> groupByField(Collection collection, final String fieldName){ return group(collection, new Hash() { private List fieldNameList = new ArrayList<>(); @Override public int hash(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; } }}); } //---------------------------------------------------------------------------------------------- Interface start /** * 针对一个参数做相应的操作 * * @author Looly * * @param 处理参数类型 */ public static interface Consumer { /** * 接受并处理一个参数 * * @param value 参数值 * @param index 参数在集合中的索引 */ void accept(T value, int index); } /** * 针对两个参数做相应的操作,例如Map中的KEY和VALUE * * @author Looly * * @param KEY类型 * @param VALUE类型 */ public static interface KVConsumer { /** * 接受并处理一对参数 * * @param key 键 * @param value 值 * @param index 参数在集合中的索引 */ void accept(K key, V value, int index); } /** * Hash计算接口 * @author looly * * @param 被计算hash的对象类型 * @since 3.2.2 */ public static interface Hash { /** * 计算Hash值 * @param t 对象 * @return hash */ int hash(T t); } //---------------------------------------------------------------------------------------------- Interface end }