!756 优化CollUtil部分方法

Merge pull request !756 from emptypoint/v6-CollUtil-update
This commit is contained in:
Looly 2022-08-19 03:04:42 +00:00 committed by Gitee
commit 136cc3b08a
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
4 changed files with 297 additions and 186 deletions

View File

@ -1,8 +1,6 @@
package cn.hutool.core.collection;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.iter.ArrayIter;
import cn.hutool.core.collection.iter.EnumerationIter;
import cn.hutool.core.collection.iter.IterUtil;
import cn.hutool.core.collection.iter.IteratorEnumeration;
import cn.hutool.core.comparator.CompareUtil;
@ -98,12 +96,12 @@ public class CollUtil {
/**
* Iterator是否为空
*
* @param Iterator Iterator对象
* @param iterator Iterator对象
* @return 是否为空
* @see IterUtil#isEmpty(Iterator)
*/
public static boolean isEmpty(final Iterator<?> Iterator) {
return IterUtil.isEmpty(Iterator);
public static boolean isEmpty(final Iterator<?> iterator) {
return IterUtil.isEmpty(iterator);
}
/**
@ -209,12 +207,12 @@ public class CollUtil {
/**
* Iterator是否为空
*
* @param Iterator Iterator对象
* @param iterator Iterator对象
* @return 是否为空
* @see IterUtil#isNotEmpty(Iterator)
*/
public static boolean isNotEmpty(final Iterator<?> Iterator) {
return IterUtil.isNotEmpty(Iterator);
public static boolean isNotEmpty(final Iterator<?> iterator) {
return IterUtil.isNotEmpty(iterator);
}
/**
@ -317,15 +315,18 @@ public class CollUtil {
return ListUtil.of(coll1);
}
final ArrayList<T> list = new ArrayList<>(Math.max(coll1.size(), coll2.size()));
// 给每个元素计数
final Map<T, Integer> map1 = countMap(coll1);
final Map<T, Integer> map2 = countMap(coll2);
final Set<T> elts = SetUtil.of(coll2);
elts.addAll(coll1);
int m;
for (final 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++) {
// 两个集合的全部元素
final Set<T> elements = SetUtil.of(map1.keySet());
elements.addAll(map2.keySet());
// 并集, 每个元素至少会有一个
final List<T> list = new ArrayList<>(elements.size());
for (final T t : elements) {
// 每个元素 保留最多的个数
int amount = Math.max(map1.getOrDefault(t, 0), map2.getOrDefault(t, 0));
for (int i = 0; i < amount; i++) {
list.add(t);
}
}
@ -405,13 +406,19 @@ public class CollUtil {
*/
@SafeVarargs
public static <T> List<T> unionAll(final Collection<T> coll1, final Collection<T> coll2, final Collection<T>... otherColls) {
final List<T> result;
if (isEmpty(coll1)) {
result = new ArrayList<>();
} else {
result = new ArrayList<>(coll1);
// 先统计所有集合的元素数量, 避免扩容
int totalSize = size(coll1) + size(coll2);
for (Collection<T> coll : otherColls) {
totalSize += size(coll);
}
if (totalSize == 0) {
return ListUtil.zero();
}
final List<T> result = new ArrayList<>(totalSize);
if (isNotEmpty(coll1)) {
result.addAll(coll1);
}
if (isNotEmpty(coll2)) {
result.addAll(coll2);
}
@ -440,21 +447,24 @@ public class CollUtil {
*/
public static <T> Collection<T> intersection(final Collection<T> coll1, final Collection<T> coll2) {
if (isNotEmpty(coll1) && isNotEmpty(coll2)) {
final ArrayList<T> list = new ArrayList<>(Math.min(coll1.size(), coll2.size()));
final Map<T, Integer> map1 = countMap(coll1);
final Map<T, Integer> map2 = countMap(coll2);
final Set<T> elts = SetUtil.of(coll2);
int m;
for (final 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++) {
boolean isFirstSmaller = map1.keySet().size() <= map2.keySet().size();
// 只需要遍历数量较少的集合的元素
final Set<T> elements = SetUtil.of(isFirstSmaller ? map1.keySet() : map2.keySet());
// 交集的元素个数 最多为 较少集合的元素个数
final List<T> list = new ArrayList<>(isFirstSmaller ? coll1.size() : coll2.size());
for (final T t : elements) {
int amount = Math.min(map1.getOrDefault(t, 0), map2.getOrDefault(t, 0));
for (int i = 0; i < amount; i++) {
list.add(t);
}
}
return list;
}
return new ArrayList<>();
return ListUtil.zero();
}
/**
@ -471,15 +481,16 @@ public class CollUtil {
*/
@SafeVarargs
public static <T> Collection<T> intersection(final Collection<T> coll1, final Collection<T> coll2, final Collection<T>... otherColls) {
// 任意容器为空, 则返回空集
if (isEmpty(coll1) || isEmpty(coll2) || ArrayUtil.hasEmpty((Object[]) otherColls)) {
return ListUtil.zero();
}
Collection<T> intersection = intersection(coll1, coll2);
if (isEmpty(intersection)) {
if (ArrayUtil.isEmpty(otherColls)) {
return intersection;
}
for (final Collection<T> coll : otherColls) {
intersection = intersection(intersection, coll);
if (isEmpty(intersection)) {
return intersection;
}
}
return intersection;
}
@ -499,26 +510,18 @@ public class CollUtil {
*/
@SafeVarargs
public static <T> Set<T> intersectionDistinct(final Collection<T> coll1, final Collection<T> coll2, final Collection<T>... otherColls) {
final Set<T> result;
if (isEmpty(coll1) || isEmpty(coll2)) {
// 有一个空集合就直接返回空
// 任意容器为空, 则返回空集
if (isEmpty(coll1) || isEmpty(coll2) || ArrayUtil.hasEmpty((Object[]) otherColls)) {
return new LinkedHashSet<>();
} else {
result = new LinkedHashSet<>(coll1);
}
final Set<T> result = new LinkedHashSet<>(coll1);
result.retainAll(coll2);
if (ArrayUtil.isNotEmpty(otherColls)) {
for (final Collection<T> otherColl : otherColls) {
if (isNotEmpty(otherColl)) {
result.retainAll(otherColl);
} else {
// 有一个空集合就直接返回空
return new LinkedHashSet<>();
}
}
}
result.retainAll(coll2);
return result;
}
@ -542,22 +545,26 @@ public class CollUtil {
* @return 差集的集合返回 {@link ArrayList}
*/
public static <T> Collection<T> disjunction(final Collection<T> coll1, final Collection<T> coll2) {
if (isEmpty(coll1)) {
if (isEmpty(coll1) || isEmpty(coll2)) {
if (isEmpty(coll1) && isEmpty(coll2)) {
return ListUtil.zero();
} else if (isEmpty(coll1)) {
return coll2;
}
if (isEmpty(coll2)) {
} else if (isEmpty(coll2)) {
return coll1;
}
}
final List<T> result = new ArrayList<>();
final Map<T, Integer> map1 = countMap(coll1);
final Map<T, Integer> map2 = countMap(coll2);
final Set<T> elts = SetUtil.of(coll2);
elts.addAll(coll1);
int m;
for (final 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++) {
// 两个集合的全部元素
final Set<T> elements = SetUtil.of(map1.keySet());
elements.addAll(map2.keySet());
// 元素的个数为 该元素在两个集合中的个数的差
for (final T t : elements) {
int amount = Math.abs(map1.getOrDefault(t, 0) - map2.getOrDefault(t, 0));
for (int i = 0; i < amount; i++) {
result.add(t);
}
}
@ -643,7 +650,6 @@ public class CollUtil {
* @since 5.7.16
*/
public static boolean safeContains(final Collection<?> collection, final Object value) {
try {
return contains(collection, value);
} catch (final ClassCastException | NullPointerException e) {
@ -677,7 +683,7 @@ public class CollUtil {
*
* @param coll1 集合1
* @param coll2 集合2
* @return 其中一个集合在另一个集合中是否至少包含一个元素
* @return 两个集合是否至少有一个共同的元素
* @see #intersection
* @since 2.1
*/
@ -685,24 +691,22 @@ public class CollUtil {
if (isEmpty(coll1) || isEmpty(coll2)) {
return false;
}
if (coll1.size() < coll2.size()) {
for (final Object object : coll1) {
if (coll2.contains(object)) {
boolean isFirstSmaller = coll1.size() <= coll2.size();
// 用元素较少的集合来遍历
final Collection<?> smallerColl = isFirstSmaller ? coll1 : coll2;
// 用元素较多的集合构造Set, 用于快速判断是否有相同元素
final Set<?> biggerSet = isFirstSmaller ? new HashSet<>(coll2) : new HashSet<>(coll1);
for (final Object object : smallerColl) {
if (biggerSet.contains(object)) {
return true;
}
}
} else {
for (final Object object : coll2) {
if (coll1.contains(object)) {
return true;
}
}
}
return false;
}
/**
* 集合1中是否包含集合2中所有的元素即集合2是否为集合1的子集
* 集合1中是否包含集合2中所有的元素即集合2是否为集合1的子集, 不考虑元素的个数<br>
* 空集是所有集合的子集<br>
*
* @param coll1 集合1
* @param coll2 集合2
@ -722,8 +726,33 @@ public class CollUtil {
return false;
}
for (final Object object : coll2) {
if (false == coll1.contains(object)) {
// 针对Set的优化
if (coll1 instanceof Set) {
//noinspection SuspiciousMethodCalls
return coll1.containsAll(coll2);
}
final Iterator<?> iterator = coll1.iterator();
// 保存 集合1 已经遍历过的元素
final Set<Object> elementsAlreadySeen = new HashSet<>();
for (final Object curElement : coll2) {
// 集合2的当前元素 已经在集合1中
if (elementsAlreadySeen.contains(curElement)) {
continue;
}
// 集合2的当前元素 是否在集合1中
boolean foundCurrentElement = false;
while (iterator.hasNext()) {
final Object next = iterator.next();
elementsAlreadySeen.add(next);
if (Objects.equals(curElement, next)) {
foundCurrentElement = true;
break;
}
}
// 集合2的当前元素 不在集合1中, 显然不是子集
if (!foundCurrentElement) {
return false;
}
}
@ -744,7 +773,7 @@ public class CollUtil {
* @see IterUtil#countMap(Iterator)
*/
public static <T> Map<T, Integer> countMap(final Iterable<T> collection) {
return IterUtil.countMap(null == collection ? null : collection.iterator());
return IterUtil.countMap(IterUtil.getIter(collection));
}
/**
@ -759,10 +788,7 @@ public class CollUtil {
* @since 5.6.7
*/
public static <T> String join(final Iterable<T> iterable, final CharSequence conjunction, final Function<T, ? extends CharSequence> func) {
if (null == iterable) {
return null;
}
return IterUtil.join(iterable.iterator(), conjunction, func);
return IterUtil.join(IterUtil.getIter(iterable), conjunction, func);
}
/**
@ -814,19 +840,15 @@ public class CollUtil {
return ListUtil.empty();
}
final List<T> currentAlaDatas = new ArrayList<>();
final int size = surplusAlaDatas.size();
// 需要切割的数量
final int popSize = Math.min(partSize, size);
final List<T> resultList = new ArrayList<>(popSize);
// 切割
if (size > partSize) {
for (int i = 0; i < partSize; i++) {
currentAlaDatas.add(surplusAlaDatas.pop());
for (int i = 0; i < popSize; i++) {
resultList.add(surplusAlaDatas.pop());
}
} else {
for (int i = 0; i < size; i++) {
currentAlaDatas.add(surplusAlaDatas.pop());
}
}
return currentAlaDatas;
return resultList;
}
/**
@ -843,19 +865,15 @@ public class CollUtil {
return ListUtil.empty();
}
final List<T> currentAlaDatas = new ArrayList<>();
final int size = surplusAlaDatas.size();
// 需要切割的数量
final int popSize = Math.min(partSize, size);
final List<T> resultList = new ArrayList<>(popSize);
// 切割
if (size > partSize) {
for (int i = 0; i < partSize; i++) {
currentAlaDatas.add(surplusAlaDatas.pop());
for (int i = 0; i < popSize; i++) {
resultList.add(surplusAlaDatas.pop());
}
} else {
for (int i = 0; i < size; i++) {
currentAlaDatas.add(surplusAlaDatas.pop());
}
}
return currentAlaDatas;
return resultList;
}
/**
@ -880,7 +898,6 @@ public class CollUtil {
/**
* 根据给定的集合类型返回对应的空集合支持类型包括
* *
* <pre>
* 1. NavigableSet
* 2. SortedSet
@ -1125,7 +1142,7 @@ public class CollUtil {
* @param <T> 集合类型
* @param <E> 集合元素类型
* @param collection 集合
* @param elesRemoved 被去掉的元素数组
* @param elesRemoved 需要删除的元素
* @return 原集合
* @since 4.1.0
*/
@ -1484,12 +1501,12 @@ public class CollUtil {
}
int matchIndex = -1;
if (isNotEmpty(collection)) {
int index = collection.size();
int index = 0;
for (final T t : collection) {
if (null == predicate || predicate.test(t)) {
matchIndex = index;
}
index--;
index++;
}
}
return matchIndex;
@ -1641,7 +1658,7 @@ public class CollUtil {
* @return {@link Enumeration}
*/
public static <E> Enumeration<E> asEnumeration(final Iterator<E> iter) {
return new IteratorEnumeration<>(iter);
return new IteratorEnumeration<>(Objects.requireNonNull(iter));
}
/**
@ -1659,7 +1676,7 @@ public class CollUtil {
}
/**
* {@link Iterator} 转为 {@link Iterable}
* {@link Iterator} 转为 {@link Iterable}, 但是仅可使用一次
*
* @param <E> 元素类型
* @param iter {@link Iterator}
@ -1680,7 +1697,7 @@ public class CollUtil {
* @since 3.0.9
*/
public static <E> Collection<E> toCollection(final Iterable<E> iterable) {
return (iterable instanceof Collection) ? (Collection<E>) iterable : ListUtil.of(iterable.iterator());
return (iterable instanceof Collection) ? (Collection<E>) iterable : ListUtil.of(IterUtil.getIter(iterable));
}
/**
@ -1787,21 +1804,13 @@ public class CollUtil {
}
final 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 EnumerationIter<>((Enumeration) value);
} else if (ArrayUtil.isArray(value)) {
iter = new ArrayIter<>(value);
} else if (value instanceof CharSequence) {
// 对字符串的特殊处理
if (value instanceof CharSequence) {
// String按照逗号分隔的列表对待
final String ArrayStr = StrUtil.unWrap((CharSequence) value, '[', ']');
iter = StrUtil.splitTrim(ArrayStr, CharUtil.COMMA).iterator();
final String arrayStr = StrUtil.unWrap((CharSequence) value, '[', ']');
iter = StrUtil.splitTrim(arrayStr, CharUtil.COMMA).iterator();
} else {
// 其它类型按照单一元素处理
iter = ListUtil.of(value).iterator();
iter = IterUtil.getIter(value);
}
final CompositeConverter convert = CompositeConverter.getInstance();
@ -1900,15 +1909,11 @@ public class CollUtil {
* @since 4.0.6
*/
public static <T> T get(final Collection<T> collection, int index) {
if (null == collection) {
if (isEmpty(collection)) {
return null;
}
final int size = collection.size();
if (0 == size) {
return null;
}
if (index < 0) {
index += size;
}
@ -1937,8 +1942,11 @@ public class CollUtil {
*/
@SuppressWarnings("unchecked")
public static <T> List<T> getAny(final Collection<T> collection, final int... indexes) {
if (isEmpty(collection) || ArrayUtil.isEmpty(indexes)) {
return ListUtil.zero();
}
final int size = collection.size();
final ArrayList<T> result = new ArrayList<>();
final List<T> result = new ArrayList<>(indexes.length);
if (collection instanceof List) {
final List<T> list = ((List<T>) collection);
for (int index : indexes) {
@ -2320,7 +2328,18 @@ public class CollUtil {
* @since 4.5.12
*/
public static <V> List<V> values(final Collection<Map<?, V>> mapCollection) {
final List<V> values = new ArrayList<>();
if (isEmpty(mapCollection)) {
return ListUtil.zero();
}
// 统计每个map的values的大小总和
int size = 0;
for (Map<?, V> map : mapCollection) {
size += size(map.values());
}
if (size == 0) {
return ListUtil.zero();
}
final List<V> values = new ArrayList<>(size);
for (final Map<?, V> map : mapCollection) {
values.addAll(map.values());
}
@ -2398,10 +2417,19 @@ public class CollUtil {
padRight(list, minLen, padObj);
return;
}
// 已达到最小长度, 不需要填充
if (list.size() >= minLen) {
return;
}
if (list instanceof ArrayList) {
// 避免频繁移动元素
list.addAll(0, Collections.nCopies(minLen - list.size(), padObj));
} else {
for (int i = list.size(); i < minLen; i++) {
list.add(0, padObj);
}
}
}
/**
* 填充List以达到最小长度
@ -2434,7 +2462,7 @@ public class CollUtil {
}
/**
* 使用给定的map将集合中的素进行属性或者值的重新设定
* 使用给定的map将集合中的素进行属性或者值的重新设定
*
* @param <E> 元素类型
* @param <K> 替换的键
@ -2510,27 +2538,28 @@ public class CollUtil {
return 0;
}
int total = 0;
if (object instanceof Map<?, ?>) {
total = ((Map<?, ?>) object).size();
} else if (object instanceof Collection<?>) {
total = ((Collection<?>) object).size();
// 优先判断使用频率较高的类型
if (object instanceof Collection<?>) {
return ((Collection<?>) object).size();
} else if (object instanceof Map<?, ?>) {
return ((Map<?, ?>) object).size();
} else if (object instanceof Iterable<?>) {
total = IterUtil.size((Iterable<?>) object);
return IterUtil.size((Iterable<?>) object);
} else if (object instanceof Iterator<?>) {
total = IterUtil.size((Iterator<?>) object);
return IterUtil.size((Iterator<?>) object);
} else if (object instanceof Enumeration<?>) {
int total = 0;
final Enumeration<?> it = (Enumeration<?>) object;
while (it.hasMoreElements()) {
total++;
it.nextElement();
}
return total;
} else if (ArrayUtil.isArray(object)) {
total = ArrayUtil.length(object);
return ArrayUtil.length(object);
} else {
throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName());
}
return total;
}
/**
@ -2557,6 +2586,41 @@ public class CollUtil {
return IterUtil.isEqualList(list1, list2);
}
/**
* 判断两个集合是否包含相同的元素(包括个数)
*
* @param coll1 集合1
* @param coll2 集合2
* @return 两个集合是否相同
* @since 6.0.0
*/
public static boolean isEquals(final Collection<?> coll1, final Collection<?> coll2) {
if (coll1 == coll2) {
return true;
}
if (coll1 == null || coll2 == null || coll1.size() != coll2.size()) {
return false;
}
// 针对 Set 的优化
if (coll1 instanceof Set || coll2 instanceof Set) {
//noinspection SuspiciousMethodCalls
return coll1 instanceof Set ? coll1.containsAll(coll2) : coll2.containsAll(coll1);
}
// 给集合1的每个元素计数
//noinspection unchecked
final Map<Object, Integer> countMap1 = countMap((Iterable<Object>) coll1);
for (Object e : coll2) {
// 该元素若存在, 则个数减去1, 若不存在则个数为-1
final Integer amount = countMap1.merge(e, -1, Integer::sum);
if (amount < 0) {
return false;
}
}
return true;
}
/**
* 一个对象不为空且不存在于该集合中时加入到该集合中<br>
* <pre>
@ -2582,4 +2646,5 @@ public class CollUtil {
}
return collection.add(object);
}
}

View File

@ -59,11 +59,11 @@ public class IterUtil {
/**
* Iterator是否为空
*
* @param Iterator Iterator对象
* @param iterator Iterator对象
* @return 是否为空
*/
public static boolean isEmpty(final Iterator<?> Iterator) {
return null == Iterator || false == Iterator.hasNext();
public static boolean isEmpty(final Iterator<?> iterator) {
return null == iterator || false == iterator.hasNext();
}
/**
@ -79,11 +79,11 @@ public class IterUtil {
/**
* Iterator是否为空
*
* @param Iterator Iterator对象
* @param iterator Iterator对象
* @return 是否为空
*/
public static boolean isNotEmpty(final Iterator<?> Iterator) {
return null != Iterator && Iterator.hasNext();
public static boolean isNotEmpty(final Iterator<?> iterator) {
return null != iterator && iterator.hasNext();
}
/**
@ -145,12 +145,10 @@ public class IterUtil {
* @return {@link Map}
*/
public static <T> Map<T, Integer> countMap(final Iterator<T> iter) {
final HashMap<T, Integer> countMap = new HashMap<>();
final Map<T, Integer> countMap = new HashMap<>();
if (null != iter) {
T t;
while (iter.hasNext()) {
t = iter.next();
countMap.put(t, countMap.getOrDefault(t, 0) + 1);
countMap.merge(iter.next(), 1, Integer::sum);
}
}
return countMap;
@ -447,11 +445,11 @@ public class IterUtil {
* @return {@link Iterator}
*/
public static <E> Iterator<E> asIterator(final Enumeration<E> e) {
return new EnumerationIter<>(e);
return new EnumerationIter<>(Objects.requireNonNull(e));
}
/**
* {@link Iterator} 转为 {@link Iterable}
* {@link Iterator} 转为 {@link Iterable}, 但是仅可使用一次
*
* @param <E> 元素类型
* @param iter {@link Iterator}
@ -838,6 +836,7 @@ public class IterUtil {
*
* @param obj 可以获取{@link Iterator}的对象
* @return {@link Iterator}如果提供对象为{@code null}返回{@code null}
* @since 5.8.0
*/
public static Iterator<?> getIter(final Object obj) {
if (obj == null) {

View File

@ -433,25 +433,15 @@ public class MapUtil {
* @return Map
*/
public static <K, V> Map<K, List<V>> toListMap(final Iterable<? extends Map<K, V>> mapList) {
final HashMap<K, List<V>> resultMap = new HashMap<>();
final Map<K, List<V>> resultMap = new HashMap<>();
if (CollUtil.isEmpty(mapList)) {
return resultMap;
}
Set<Entry<K, V>> entrySet;
for (final Map<K, V> map : mapList) {
entrySet = map.entrySet();
K key;
List<V> valueList;
for (final Entry<K, V> entry : entrySet) {
key = entry.getKey();
valueList = resultMap.get(key);
if (null == valueList) {
valueList = ListUtil.of(entry.getValue());
resultMap.put(key, valueList);
} else {
valueList.add(entry.getValue());
}
for (final Entry<K, V> entry : map.entrySet()) {
resultMap.computeIfAbsent(entry.getKey(), k -> new ArrayList<>())
.add(entry.getValue());
}
}
@ -488,35 +478,31 @@ public class MapUtil {
* @return Map列表
*/
public static <K, V> List<Map<K, V>> toMapList(final Map<K, ? extends Iterable<V>> listMap) {
final List<Map<K, V>> resultList = new ArrayList<>();
if (isEmpty(listMap)) {
return resultList;
return ListUtil.zero();
}
boolean isEnd;// 是否结束标准是元素列表已耗尽
int index = 0;// 值索引
Map<K, V> map;
do {
isEnd = true;
map = new HashMap<>();
List<V> vList;
int vListSize;
for (final Entry<K, ? extends Iterable<V>> entry : listMap.entrySet()) {
vList = ListUtil.of(entry.getValue());
vListSize = vList.size();
if (index < vListSize) {
map.put(entry.getKey(), vList.get(index));
if (index != vListSize - 1) {
// 当值列表中还有更多值非最后一个继续循环
isEnd = false;
final List<Map<K, V>> resultList = new ArrayList<>();
for (Entry<K, ? extends Iterable<V>> entry : listMap.entrySet()) {
final Iterator<V> iterator = IterUtil.getIter(entry.getValue());
if (IterUtil.isEmpty(iterator)) {
continue;
}
final K key = entry.getKey();
// 对已经存在的map添加元素
for (Map<K, V> map : resultList) {
// 还可以继续添加元素
if (iterator.hasNext()) {
map.put(key, iterator.next());
} else {
break;
}
}
// entry的value的个数 大于 当前列表的size, 直接新增map
while (iterator.hasNext()) {
resultList.add(MapUtil.of(key, iterator.next()));
}
if (false == map.isEmpty()) {
resultList.add(map);
}
index++;
} while (false == isEnd);
return resultList;
}

View File

@ -29,8 +29,10 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Queue;
import java.util.Set;
import java.util.SortedSet;
import java.util.Stack;
import java.util.function.Function;
/**
@ -816,8 +818,14 @@ public class CollUtilTest {
public void lastIndexOfTest() {
// List有优化
final ArrayList<String> list = ListUtil.of("a", "b", "c", "c", "a", "b", "d");
final int i = CollUtil.lastIndexOf(list, (str) -> str.charAt(0) == 'c');
Assert.assertEquals(3, i);
final int i = CollUtil.lastIndexOf(list, (str) -> str.charAt(0) == 'a');
Assert.assertEquals(4, i);
final Queue<Integer> set = new ArrayDeque<>(Arrays.asList(1, 2, 3, 3, 2, 1));
Assert.assertEquals(5, CollUtil.lastIndexOf(set, num -> num.equals(1)));
Assert.assertEquals(4, CollUtil.lastIndexOf(set, num -> num.equals(2)));
Assert.assertEquals(3, CollUtil.lastIndexOf(set, num -> num.equals(3)));
Assert.assertEquals(-1, CollUtil.lastIndexOf(set, num -> num.equals(4)));
}
@Test
@ -1003,6 +1011,11 @@ public class CollUtilTest {
final List<String> list3 = null;
final List<String> list = CollUtil.unionAll(list1, list2, list3);
Assert.assertNotNull(list);
Assert.assertEquals(
ListUtil.of(1, 2, 3, 4),
CollUtil.unionAll(ListUtil.of(1), ListUtil.of(2), ListUtil.of(3), ListUtil.of(4))
);
}
@SuppressWarnings("ConstantConditions")
@ -1075,4 +1088,52 @@ public class CollUtilTest {
deque.add("4");
Assert.assertEquals("3", CollUtil.getFirst(deque));
}
@Test
public void popPartTest() {
final Stack<Integer> stack = new Stack<>();
for (int i = 0; i < 10; i++) {
stack.push(i);
}
final List<Integer> popPart1 = CollUtil.popPart(stack, 3);
Assert.assertEquals(ListUtil.of(9, 8, 7), popPart1);
Assert.assertEquals(7, stack.size());
final ArrayDeque<Integer> queue = new ArrayDeque<>();
for (int i = 0; i < 10; i++) {
queue.push(i);
}
final List<Integer> popPart2 = CollUtil.popPart(queue, 3);
Assert.assertEquals(ListUtil.of(9, 8, 7), popPart2);
Assert.assertEquals(7, queue.size());
}
@Test
public void isEqualListTest() {
final List<Integer> list = ListUtil.of(1, 2, 3, 4);
Assert.assertTrue(CollUtil.isEqualList(null, null));
Assert.assertTrue(CollUtil.isEqualList(ListUtil.of(), ListUtil.of()));
Assert.assertTrue(CollUtil.isEqualList(list, list));
Assert.assertTrue(CollUtil.isEqualList(list, ListUtil.of(1, 2, 3, 4)));
Assert.assertFalse(CollUtil.isEqualList(null, ListUtil.of()));
Assert.assertFalse(CollUtil.isEqualList(list, ListUtil.of(1, 2, 3, 3)));
Assert.assertFalse(CollUtil.isEqualList(list, ListUtil.of(1, 2, 3)));
Assert.assertFalse(CollUtil.isEqualList(list, ListUtil.of(4, 3, 2, 1)));
}
@Test
public void isEqualsTest() {
final List<Integer> list = ListUtil.of(1, 2, 3, 4);
Assert.assertTrue(CollUtil.isEquals(null, null));
Assert.assertTrue(CollUtil.isEquals(ListUtil.of(), ListUtil.of()));
Assert.assertTrue(CollUtil.isEquals(list, list));
Assert.assertTrue(CollUtil.isEquals(list, ListUtil.of(1, 2, 3, 4)));
Assert.assertTrue(CollUtil.isEquals(list, ListUtil.of(4, 3, 2, 1)));
Assert.assertTrue(CollUtil.isEquals(list, SetUtil.of(4, 3, 2, 1)));
Assert.assertFalse(CollUtil.isEquals(null, ListUtil.of()));
Assert.assertFalse(CollUtil.isEquals(list, ListUtil.of(1, 2, 3, 3)));
Assert.assertFalse(CollUtil.isEquals(list, ListUtil.of(1, 2, 3)));
}
}