This commit is contained in:
Looly 2022-06-18 22:03:45 +08:00
parent 08b6716ca7
commit 3f678427b3
8 changed files with 285 additions and 423 deletions

View File

@ -4,6 +4,7 @@ import cn.hutool.core.bean.copier.BeanCopier;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.bean.copier.ValueProvider;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.collection.SetUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.func.Editor;
@ -318,7 +319,7 @@ public class BeanUtil {
if (bean instanceof Map) {
((Map) bean).put(fieldNameOrIndex, value);
} else if (bean instanceof List) {
CollUtil.setOrAppend((List) bean, Convert.toInt(fieldNameOrIndex), value);
ListUtil.setOrAppend((List) bean, Convert.toInt(fieldNameOrIndex), value);
} else if (ArrayUtil.isArray(bean)) {
ArrayUtil.setOrAppend(bean, Convert.toInt(fieldNameOrIndex), value);
} else {

View File

@ -11,7 +11,6 @@ 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.func.Func1;
import cn.hutool.core.lang.hash.Hash32;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.reflect.ClassUtil;
@ -64,18 +63,16 @@ import java.util.stream.Collectors;
/**
* 集合相关工具类
* <p>
* 此工具方法针对{@link Collection}及其实现类封装的工具
* 此工具方法针对{@link Collection}{@link Iterable}及其实现类封装的工具
* <p>
* 由于{@link Collection} 实现了{@link Iterable}接口因此部分工具此类不提供而是在{@link IterUtil} 中提供
*
* @author xiaoleilu
* @author Looly
* @see IterUtil
* @since 3.1.1
*/
public class CollUtil {
// ---------------------------------------------------------------------- isEmpty
/**
* 集合是否为空
*
@ -868,6 +865,44 @@ public class CollUtil {
return queue;
}
/**
* 根据给定的集合类型返回对应的空集合支持类型包括
* *
* <pre>
* 1. NavigableSet
* 2. SortedSet
* 3. Set
* 4. List
* </pre>
*
* @param <E> 元素类型
* @param <T> 集合类型
* @param collectionClass 集合类型
* @return 空集合
* @since 5.3.1
*/
@SuppressWarnings("unchecked")
public static <E, T extends Collection<E>> T empty(final 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));
}
/**
* 创建新的集合对象
*
@ -1085,17 +1120,26 @@ public class CollUtil {
}
/**
* 去除指定元素此方法直接修改原集合
* 移除集合中满足条件的所有元素此方法在原集合上直接修改<br>
* 通过实现{@link Predicate}接口完成元素的移除可以实现以下功能
*
* <pre>
* 1移除指定对象{@link Predicate#test(Object)}方法返回{@code true}的对象将被使用{@link Iterator#remove()}方法移除
* </pre>
*
* @param <T> 集合类型
* @param <E> 集合元素类型
* @param collection 集合
* @param filter 过滤器
* @return 处理后的集合
* @param iter 集合
* @param predicate 过滤器接口
* @return 编辑后的集合
* @since 4.6.5
*/
public static <T extends Collection<E>, E> T remove(final T collection, final Predicate<E> filter) {
return IterUtil.remove(collection, filter);
public static <T extends Iterable<E>, E> T remove(final T iter, final Predicate<E> predicate) {
if (null == iter) {
return null;
}
IterUtil.remove(iter.iterator(), predicate);
return iter;
}
/**
@ -1297,6 +1341,29 @@ public class CollUtil {
return IterUtil.fieldValueAsMap(IterUtil.getIter(iterable), fieldNameForKey, fieldNameForValue);
}
/**
* 获取集合的第一个元素如果集合为空null或者空集合返回{@code null}
*
* @param <T> 集合元素类型
* @param iterable {@link Iterable}
* @return 第一个元素为空返回{@code null}
*/
public static <T> T getFirst(final Iterable<T> iterable) {
return IterUtil.getFirst(IterUtil.getIter(iterable));
}
/**
* 获取集合的第一个非空元素
*
* @param <T> 集合元素类型
* @param iterable {@link Iterable}
* @return 第一个元素
* @since 5.7.2
*/
public static <T> T getFirstNoneNull(final Iterable<T> iterable) {
return IterUtil.getFirstNoneNull(IterUtil.getIter(iterable));
}
/**
* 查找第一个匹配元素对象
*
@ -1306,15 +1373,8 @@ public class CollUtil {
* @return 满足过滤条件的第一个元素
* @since 3.1.0
*/
public static <T> T findOne(final Iterable<T> collection, final Predicate<T> predicate) {
if (null != collection) {
for (final T t : collection) {
if (predicate.test(t)) {
return t;
}
}
}
return null;
public static <T> T getFirst(final Iterable<T> collection, final Predicate<T> predicate) {
return IterUtil.getFirst(IterUtil.getIter(collection), predicate);
}
/**
@ -1330,8 +1390,8 @@ public class CollUtil {
* @return 满足条件的第一个元素
* @since 3.1.0
*/
public static <T> T findOneByField(final Iterable<T> collection, final String fieldName, final Object fieldValue) {
return findOne(collection, t -> {
public static <T> T getFirstByField(final Iterable<T> collection, final String fieldName, final Object fieldValue) {
return getFirst(collection, t -> {
if (t instanceof Map) {
final Map<?, ?> map = (Map<?, ?>) t;
final Object value = map.get(fieldName);
@ -1509,19 +1569,6 @@ public class CollUtil {
return map;
}
/**
* 将Entry集合转换为HashMap
*
* @param <K> 键类型
* @param <V> 值类型
* @param entryIter entry集合
* @return Map
* @see IterUtil#toMap(Iterable)
*/
public static <K, V> HashMap<K, V> toMap(final Iterable<Entry<K, V>> entryIter) {
return IterUtil.toMap(entryIter);
}
/**
* 将数组转换为MapHashMap支持数组元素类型为
*
@ -1685,40 +1732,6 @@ public class CollUtil {
return MapUtil.toMapList(listMap);
}
/**
* 集合转换为Map转换规则为<br>
* 按照keyFunc函数规则根据元素对象生成Key元素作为值
*
* @param <K> Map键类型
* @param <V> Map值类型
* @param values 数据列表
* @param map Map对象转换后的键值对加入此Map通过传入此对象自定义Map类型
* @param keyFunc 生成key的函数
* @return 生成的map
* @since 5.2.6
*/
public static <K, V> Map<K, V> toMap(final Iterable<V> values, final Map<K, V> map, final Func1<V, K> keyFunc) {
return IterUtil.toMap(null == values ? null : values.iterator(), map, keyFunc);
}
/**
* 集合转换为Map转换规则为<br>
* 按照keyFunc函数规则根据元素对象生成Key按照valueFunc函数规则根据元素对象生成value组成新的Map
*
* @param <K> Map键类型
* @param <V> Map值类型
* @param <E> 元素类型
* @param values 数据列表
* @param map Map对象转换后的键值对加入此Map通过传入此对象自定义Map类型
* @param keyFunc 生成key的函数
* @param valueFunc 生成值的策略函数
* @return 生成的map
* @since 5.2.6
*/
public static <K, V, E> Map<K, V> toMap(final Iterable<E> values, final Map<K, V> map, final Func1<E, K> keyFunc, final Func1<E, V> valueFunc) {
return IterUtil.toMap(null == values ? null : values.iterator(), map, keyFunc, valueFunc);
}
/**
* 将指定对象全部加入到集合中<br>
* 提供的对象如果为集合类型会自动转换为目标元素类型<br>
@ -1844,6 +1857,18 @@ public class CollUtil {
return collection;
}
/**
* 获取集合的最后一个元素
*
* @param <T> 集合元素类型
* @param collection {@link Collection}
* @return 最后一个元素
* @since 4.1.10
*/
public static <T> T getLast(final Collection<T> collection) {
return get(collection, -1);
}
/**
* 获取集合中指定下标的元素值下标可以为负数例如-1表示最后一个元素<br>
* 如果元素越界返回null
@ -1914,77 +1939,6 @@ public class CollUtil {
return result;
}
/**
* 获取集合的第一个元素
*
* @param <T> 集合元素类型
* @param iterable {@link Iterable}
* @return 第一个元素
* @see IterUtil#getFirst(Iterable)
* @since 3.0.1
*/
public static <T> T getFirst(final Iterable<T> iterable) {
return IterUtil.getFirst(iterable);
}
/**
* 获取集合的最后一个元素
*
* @param <T> 集合元素类型
* @param collection {@link Collection}
* @return 最后一个元素
* @since 4.1.10
*/
public static <T> T getLast(final Collection<T> collection) {
return get(collection, -1);
}
/**
* 从Map中获取指定键列表对应的值列表<br>
* 如果key在map中不存在或key对应值为null则返回值列表对应位置的值也为null
*
* @param <K> 键类型
* @param <V> 值类型
* @param map {@link Map}
* @param keys 键列表
* @return 值列表
* @since 3.0.8
*/
@SuppressWarnings("unchecked")
public static <K, V> ArrayList<V> valuesOfKeys(final Map<K, V> map, final K... keys) {
return MapUtil.valuesOfKeys(map, new ArrayIter<>(keys));
}
/**
* 从Map中获取指定键列表对应的值列表<br>
* 如果key在map中不存在或key对应值为null则返回值列表对应位置的值也为null
*
* @param <K> 键类型
* @param <V> 值类型
* @param map {@link Map}
* @param keys 键列表
* @return 值列表
* @since 3.0.9
*/
public static <K, V> ArrayList<V> valuesOfKeys(final Map<K, V> map, final Iterable<K> keys) {
return valuesOfKeys(map, keys.iterator());
}
/**
* 从Map中获取指定键列表对应的值列表<br>
* 如果key在map中不存在或key对应值为null则返回值列表对应位置的值也为null
*
* @param <K> 键类型
* @param <V> 值类型
* @param map {@link Map}
* @param keys 键列表
* @return 值列表
* @since 3.0.9
*/
public static <K, V> ArrayList<V> valuesOfKeys(final Map<K, V> map, final Iterator<K> keys) {
return MapUtil.valuesOfKeys(map, keys);
}
// ------------------------------------------------------------------------------------------------- sort
/**
@ -2317,20 +2271,6 @@ public class CollUtil {
});
}
/**
* 设置或增加元素当index小于List的长度时替换指定位置的值否则在尾部追加
*
* @param <T> 元素类型
* @param list List列表
* @param index 位置
* @param element 新元素
* @return 原List
* @since 4.1.2
*/
public static <T> List<T> setOrAppend(final List<T> list, final int index, final T element) {
return ListUtil.setOrAppend(list, index, element);
}
/**
* 获取指定Map列表中所有的Key
*
@ -2409,44 +2349,6 @@ public class CollUtil {
return Collections.unmodifiableCollection(c);
}
/**
* 根据给定的集合类型返回对应的空集合支持类型包括
* *
* <pre>
* 1. NavigableSet
* 2. SortedSet
* 3. Set
* 4. List
* </pre>
*
* @param <E> 元素类型
* @param <T> 集合类型
* @param collectionClass 集合类型
* @return 空集合
* @since 5.3.1
*/
@SuppressWarnings("unchecked")
public static <E, T extends Collection<E>> T empty(final 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()方法
*
@ -2571,11 +2473,11 @@ public class CollUtil {
/**
* 获取Collection或者iterator的大小此方法可以处理的对象类型如下
* <ul>
* <li>Collection - the collection size
* <li>Map - the map size
* <li>Array - the array size
* <li>Iterator - the number of elements remaining in the iterator
* <li>Enumeration - the number of elements remaining in the enumeration
* <li>Collection - the collection size</li>
* <li>Map - the map size</li>
* <li>Array - the array size</li>
* <li>Iterator - the number of elements remaining in the iterator</li>
* <li>Enumeration - the number of elements remaining in the enumeration</li>
* </ul>
*
* @param object 可以为空的对象

View File

@ -1,11 +1,8 @@
package cn.hutool.core.collection.iter;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.func.Filter;
import cn.hutool.core.lang.func.Func1;
import cn.hutool.core.lang.func.Matcher;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.reflect.FieldUtil;
import cn.hutool.core.reflect.MethodUtil;
@ -24,7 +21,6 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
@ -179,7 +175,7 @@ public class IterUtil {
*/
@SuppressWarnings("unchecked")
public static <K, V> Map<K, V> fieldValueMap(final Iterator<V> iter, final String fieldName) {
return toMap(iter, new HashMap<>(), (value) -> (K) FieldUtil.getFieldValue(value, fieldName));
return MapUtil.putAll(new HashMap<>(), iter, (value) -> (K) FieldUtil.getFieldValue(value, fieldName));
}
/**
@ -195,7 +191,7 @@ public class IterUtil {
*/
@SuppressWarnings("unchecked")
public static <K, V> Map<K, V> fieldValueAsMap(final Iterator<?> iter, final String fieldNameForKey, final String fieldNameForValue) {
return toMap(iter, new HashMap<>(),
return MapUtil.putAll(new HashMap<>(), iter,
(value) -> (K) FieldUtil.getFieldValue(value, fieldNameForKey),
(value) -> (V) FieldUtil.getFieldValue(value, fieldNameForValue)
);
@ -287,24 +283,6 @@ public class IterUtil {
return StrJoiner.of(conjunction).append(iterator, func).toString();
}
/**
* 将Entry集合转换为HashMap
*
* @param <K> 键类型
* @param <V> 值类型
* @param entryIter entry集合
* @return Map
*/
public static <K, V> HashMap<K, V> toMap(final Iterable<Entry<K, V>> entryIter) {
final HashMap<K, V> map = new HashMap<>();
if (isNotEmpty(entryIter)) {
for (final Entry<K, V> entry : entryIter) {
map.put(entry.getKey(), entry.getValue());
}
}
return map;
}
/**
* 将键列表和值列表转换为Map<br>
* 以键为准值与键位置需对应如果键元素数多于值元素多余部分值用null代替<br>
@ -462,64 +440,7 @@ public class IterUtil {
* @since 5.3.6
*/
public static <T, K, V> Map<K, V> toMap(final Iterable<T> iterable, final Function<T, K> keyMapper, final Function<T, V> valueMapper) {
return toMap(MapUtil.newHashMap(), iterable, keyMapper, valueMapper);
}
/**
* 将列表转成Map
*
* @param resultMap 结果Map通过传入map对象决定结果的Map类型
* @param iterable 值列表
* @param keyMapper Map的键映射
* @param valueMapper Map的值映射
* @param <T> 列表值类型
* @param <K> 键类型
* @param <V> 值类型
* @return HashMap
* @since 5.3.6
*/
public static <T, K, V> Map<K, V> toMap(Map<K, V> resultMap, final Iterable<T> iterable, final Function<T, K> keyMapper, final Function<T, V> valueMapper) {
if (null == resultMap) {
resultMap = MapUtil.newHashMap();
}
if (ObjUtil.isNull(iterable)) {
return resultMap;
}
for (final T value : iterable) {
resultMap.put(keyMapper.apply(value), valueMapper.apply(value));
}
return resultMap;
}
/**
* Iterator转List<br>
* 不判断直接生成新的List
*
* @param <E> 元素类型
* @param iter {@link Iterator}
* @return List
* @since 4.0.6
*/
public static <E> List<E> toList(final Iterable<E> iter) {
if (null == iter) {
return null;
}
return toList(iter.iterator());
}
/**
* Iterator转List<br>
* 不判断直接生成新的List
*
* @param <E> 元素类型
* @param iter {@link Iterator}
* @return List
* @since 4.0.6
*/
public static <E> List<E> toList(final Iterator<E> iter) {
return ListUtil.of(iter);
return MapUtil.putAll(MapUtil.newHashMap(), iterable, keyMapper, valueMapper);
}
/**
@ -556,7 +477,7 @@ public class IterUtil {
* @since 5.8.0
*/
public static <E> E get(final Iterator<E> iterator, int index) throws IndexOutOfBoundsException {
if(null == iterator){
if (null == iterator) {
return null;
}
Assert.isTrue(index >= 0, "[index] must be >= 0");
@ -570,32 +491,6 @@ public class IterUtil {
return null;
}
/**
* 获取集合的第一个元素如果集合为空null或者空集合返回{@code null}
*
* @param <T> 集合元素类型
* @param iterable {@link Iterable}
* @return 第一个元素为空返回{@code null}
*/
public static <T> T getFirst(final Iterable<T> iterable) {
return getFirst(getIter(iterable));
}
/**
* 获取集合的第一个非空元素
*
* @param <T> 集合元素类型
* @param iterable {@link Iterable}
* @return 第一个元素
* @since 5.7.2
*/
public static <T> T getFirstNoneNull(final Iterable<T> iterable) {
if (null == iterable) {
return null;
}
return getFirstNoneNull(iterable.iterator());
}
/**
* 获取集合的第一个元素
*
@ -616,7 +511,7 @@ public class IterUtil {
* @since 5.7.2
*/
public static <T> T getFirstNoneNull(final Iterator<T> iterator) {
return firstMatch(iterator, Objects::nonNull);
return getFirst(iterator, Objects::nonNull);
}
/**
@ -624,16 +519,16 @@ public class IterUtil {
*
* @param <T> 数组元素类型
* @param iterator {@link Iterator}
* @param matcher 匹配接口实现此接口自定义匹配规则
* @param predicate 匹配接口实现此接口自定义匹配规则
* @return 匹配元素如果不存在匹配元素或{@link Iterator}为空返回 {@code null}
* @since 5.7.5
*/
public static <T> T firstMatch(final Iterator<T> iterator, final Matcher<T> matcher) {
Assert.notNull(matcher, "Matcher must be not null !");
public static <T> T getFirst(final Iterator<T> iterator, final Predicate<T> predicate) {
Assert.notNull(predicate, "Matcher must be not null !");
if (null != iterator) {
while (iterator.hasNext()) {
final T next = iterator.next();
if (matcher.match(next)) {
if (predicate.test(next)) {
return next;
}
}
@ -689,7 +584,7 @@ public class IterUtil {
}
T modified;
while(iter.hasNext()){
while (iter.hasNext()) {
modified = (null == editor) ? iter.next() : editor.apply(iter.next());
if (null != modified) {
result.add(modified);
@ -698,31 +593,6 @@ public class IterUtil {
return result;
}
/**
* 移除集合中满足条件的所有元素此方法在原集合上直接修改<br>
* 通过实现{@link Predicate}接口完成元素的移除可以实现以下功能
*
* <pre>
* 1移除指定对象{@link Predicate#test(Object)}方法返回{@code true}的对象将被使用{@link Iterator#remove()}方法移除
* </pre>
*
* @param <T> 集合类型
* @param <E> 集合元素类型
* @param iter 集合
* @param predicate 过滤器接口
* @return 编辑后的集合
* @since 4.6.5
*/
public static <T extends Iterable<E>, E> T remove(final T iter, final Predicate<E> predicate) {
if (null == iter) {
return null;
}
remove(iter.iterator(), predicate);
return iter;
}
/**
* 移除集合中满足条件的所有元素此方法在原集合上直接修改<br>
* 通过实现{@link Predicate}接口完成元素的移除可以实现以下功能
@ -760,7 +630,7 @@ public class IterUtil {
* @since 5.7.22
*/
public static <E> List<E> filterToList(final Iterator<E> iter, final Predicate<E> filter) {
return toList(filtered(iter, filter));
return ListUtil.of(filtered(iter, filter));
}
/**
@ -776,57 +646,6 @@ public class IterUtil {
return new FilterIter<>(iterator, filter);
}
/**
* Iterator转换为Map转换规则为<br>
* 按照keyFunc函数规则根据元素对象生成Key元素作为值
*
* @param <K> Map键类型
* @param <V> Map值类型
* @param iterator 数据列表
* @param map Map对象转换后的键值对加入此Map通过传入此对象自定义Map类型
* @param keyFunc 生成key的函数
* @return 生成的map
* @since 5.2.6
*/
public static <K, V> Map<K, V> toMap(final Iterator<V> iterator, final Map<K, V> map, final Func1<V, K> keyFunc) {
return toMap(iterator, map, keyFunc, (value) -> value);
}
/**
* 集合转换为Map转换规则为<br>
* 按照keyFunc函数规则根据元素对象生成Key按照valueFunc函数规则根据元素对象生成value组成新的Map
*
* @param <K> Map键类型
* @param <V> Map值类型
* @param <E> 元素类型
* @param iterator 数据列表
* @param map Map对象转换后的键值对加入此Map通过传入此对象自定义Map类型
* @param keyFunc 生成key的函数
* @param valueFunc 生成值的策略函数
* @return 生成的map
* @since 5.2.6
*/
public static <K, V, E> Map<K, V> toMap(final Iterator<E> iterator, Map<K, V> map, final Func1<E, K> keyFunc, final Func1<E, V> valueFunc) {
if (null == iterator) {
return map;
}
if (null == map) {
map = MapUtil.newHashMap(true);
}
E element;
while (iterator.hasNext()) {
element = iterator.next();
try {
map.put(keyFunc.call(element), valueFunc.call(element));
} catch (final Exception e) {
throw new UtilException(e);
}
}
return map;
}
/**
* 返回一个空Iterator
*

View File

@ -1,7 +1,7 @@
package cn.hutool.core.convert.impl;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.iter.IterUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.AbstractConverter;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.text.StrUtil;
@ -143,14 +143,14 @@ public class ArrayConverter extends AbstractConverter {
}
} else if (value instanceof Iterable) {
// 可循环对象转数组可循环对象无法获取长度因此先转为List后转为数组
final List<?> list = IterUtil.toList((Iterable<?>) value);
final List<?> list = ListUtil.of((Iterable<?>) value);
result = Array.newInstance(targetComponentType, list.size());
for (int i = 0; i < list.size(); i++) {
Array.set(result, i, convertComponentType(targetComponentType, list.get(i)));
}
} else if (value instanceof Iterator) {
// 可循环对象转数组可循环对象无法获取长度因此先转为List后转为数组
final List<?> list = IterUtil.toList((Iterator<?>) value);
final List<?> list = ListUtil.of((Iterator<?>) value);
result = Array.newInstance(targetComponentType, list.size());
for (int i = 0; i < list.size(); i++) {
Array.set(result, i, convertComponentType(targetComponentType, list.get(i)));

View File

@ -2,6 +2,8 @@ package cn.hutool.core.map;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.collection.iter.ArrayIter;
import cn.hutool.core.collection.iter.IterUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.func.Editor;
import cn.hutool.core.lang.func.Filter;
@ -9,6 +11,7 @@ import cn.hutool.core.reflect.ConstructorUtil;
import cn.hutool.core.reflect.TypeReference;
import cn.hutool.core.text.StrUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjUtil;
import java.util.AbstractMap;
import java.util.ArrayList;
@ -28,6 +31,7 @@ import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
@ -292,9 +296,37 @@ public class MapUtil {
*/
@SafeVarargs
public static <K, V> Map<K, V> ofEntries(final Map.Entry<K, V>... entries) {
final Map<K, V> map = new HashMap<>();
for (final Map.Entry<K, V> pair : entries) {
map.put(pair.getKey(), pair.getValue());
return ofEntries((Iterator<Entry<K, V>>) new ArrayIter<>(entries));
}
/**
* 将Entry集合转换为HashMap
*
* @param <K> 键类型
* @param <V> 值类型
* @param entryIter entry集合
* @return Map
*/
public static <K, V> HashMap<K, V> ofEntries(final Iterable<Entry<K, V>> entryIter) {
return ofEntries(IterUtil.getIter(entryIter));
}
/**
* 将Entry集合转换为HashMap
*
* @param <K> 键类型
* @param <V> 值类型
* @param entryIter entry集合
* @return Map
*/
public static <K, V> HashMap<K, V> ofEntries(final Iterator<Entry<K, V>> entryIter) {
final HashMap<K, V> map = new HashMap<>();
if (IterUtil.isNotEmpty(entryIter)) {
Entry<K, V> entry;
while (entryIter.hasNext()) {
entry = entryIter.next();
map.put(entry.getKey(), entry.getValue());
}
}
return map;
}
@ -1365,6 +1397,37 @@ public class MapUtil {
}
}
/**
* 从Map中获取指定键列表对应的值列表<br>
* 如果key在map中不存在或key对应值为null则返回值列表对应位置的值也为null
*
* @param <K> 键类型
* @param <V> 值类型
* @param map {@link Map}
* @param keys 键列表
* @return 值列表
* @since 3.0.8
*/
@SuppressWarnings("unchecked")
public static <K, V> ArrayList<V> valuesOfKeys(final Map<K, V> map, final K... keys) {
return valuesOfKeys(map, (Iterator<K>) new ArrayIter<>(keys));
}
/**
* 从Map中获取指定键列表对应的值列表<br>
* 如果key在map中不存在或key对应值为null则返回值列表对应位置的值也为null
*
* @param <K> 键类型
* @param <V> 值类型
* @param map {@link Map}
* @param keys 键列表
* @return 值列表
* @since 3.0.9
*/
public static <K, V> ArrayList<V> valuesOfKeys(final Map<K, V> map, final Iterable<K> keys) {
return valuesOfKeys(map, keys.iterator());
}
/**
* 从Map中获取指定键列表对应的值列表<br>
* 如果key在map中不存在或key对应值为null则返回值列表对应位置的值也为null
@ -1415,4 +1478,80 @@ public class MapUtil {
new AbstractMap.SimpleImmutableEntry<>(key, value) :
new AbstractMap.SimpleEntry<>(key, value);
}
/**
* 将列表按照给定的键生成器规则和值生成器规则加入到给定的Map中
*
* @param resultMap 结果Map通过传入map对象决定结果的Map类型如果为{@code null}默认使用HashMap
* @param iterable 值列表
* @param keyMapper Map的键映射
* @param <K> 键类型
* @param <V> 值类型
* @return HashMap
* @since 5.3.6
*/
public static <K, V> Map<K, V> putAll(final Map<K, V> resultMap, final Iterable<V> iterable, final Function<V, K> keyMapper) {
return putAll(resultMap, iterable, keyMapper, Function.identity());
}
/**
* 将列表按照给定的键生成器规则和值生成器规则加入到给定的Map中
*
* @param resultMap 结果Map通过传入map对象决定结果的Map类型
* @param iterable 值列表
* @param keyMapper Map的键映射
* @param valueMapper Map的值映射
* @param <T> 列表值类型
* @param <K> 键类型
* @param <V> 值类型
* @return HashMap
* @since 5.3.6
*/
public static <T, K, V> Map<K, V> putAll(final Map<K, V> resultMap, final Iterable<T> iterable, final Function<T, K> keyMapper, final Function<T, V> valueMapper) {
return putAll(resultMap, IterUtil.getIter(iterable), keyMapper, valueMapper);
}
/**
* 将列表按照给定的键生成器规则和值生成器规则加入到给定的Map中
*
* @param resultMap 结果Map通过传入map对象决定结果的Map类型如果为{@code null}默认使用HashMap
* @param iterator 值列表
* @param keyMapper Map的键映射
* @param <K> 键类型
* @param <V> 值类型
* @return HashMap
* @since 5.3.6
*/
public static <K, V> Map<K, V> putAll(final Map<K, V> resultMap, final Iterator<V> iterator, final Function<V, K> keyMapper) {
return putAll(resultMap, iterator, keyMapper, Function.identity());
}
/**
* 将列表按照给定的键生成器规则和值生成器规则加入到给定的Map中
*
* @param resultMap 结果Map通过传入map对象决定结果的Map类型如果为{@code null}默认使用HashMap
* @param iterator 值列表
* @param keyMapper Map的键映射
* @param valueMapper Map的值映射
* @param <T> 列表值类型
* @param <K> 键类型
* @param <V> 值类型
* @return HashMap
* @since 5.3.6
*/
public static <T, K, V> Map<K, V> putAll(Map<K, V> resultMap, final Iterator<T> iterator, final Function<T, K> keyMapper, final Function<T, V> valueMapper) {
if (null == resultMap) {
resultMap = MapUtil.newHashMap();
}
if (ObjUtil.isNull(iterator)) {
return resultMap;
}
T value;
while (iterator.hasNext()) {
value = iterator.next();
resultMap.put(keyMapper.apply(value), valueMapper.apply(value));
}
return resultMap;
}
}

View File

@ -96,23 +96,6 @@ public class CollUtilTest {
Assert.assertNotNull(set);
}
@Test
public void valuesOfKeysTest() {
final Dict v1 = Dict.create().set("id", 12).set("name", "张三").set("age", 23);
final Dict v2 = Dict.create().set("age", 13).set("id", 15).set("name", "李四");
final String[] keys = v1.keySet().toArray(new String[0]);
final ArrayList<Object> v1s = CollUtil.valuesOfKeys(v1, keys);
Assert.assertTrue(v1s.contains(12));
Assert.assertTrue(v1s.contains(23));
Assert.assertTrue(v1s.contains("张三"));
final ArrayList<Object> v2s = CollUtil.valuesOfKeys(v2, keys);
Assert.assertTrue(v2s.contains(15));
Assert.assertTrue(v2s.contains(13));
Assert.assertTrue(v2s.contains("李四"));
}
@Test
public void unionTest() {
final ArrayList<String> list1 = ListUtil.of("a", "b", "b", "c", "d", "x");

View File

@ -9,6 +9,7 @@ import org.junit.Assert;
import org.junit.Test;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@ -222,4 +223,21 @@ public class MapUtilTest {
final Integer a = MapUtil.getInt(map, "a");
Assert.assertNotNull(a);
}
@Test
public void valuesOfKeysTest() {
final Dict v1 = Dict.create().set("id", 12).set("name", "张三").set("age", 23);
final Dict v2 = Dict.create().set("age", 13).set("id", 15).set("name", "李四");
final String[] keys = v1.keySet().toArray(new String[0]);
final ArrayList<Object> v1s = MapUtil.valuesOfKeys(v1, keys);
Assert.assertTrue(v1s.contains(12));
Assert.assertTrue(v1s.contains(23));
Assert.assertTrue(v1s.contains("张三"));
final ArrayList<Object> v2s = MapUtil.valuesOfKeys(v2, keys);
Assert.assertTrue(v2s.contains(15));
Assert.assertTrue(v2s.contains(13));
Assert.assertTrue(v2s.contains("李四"));
}
}

View File

@ -1,11 +1,11 @@
package cn.hutool.db;
import cn.hutool.core.collection.iter.ArrayIter;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.StrUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.db.handler.ResultSetUtil;
import cn.hutool.db.handler.RsHandler;
import cn.hutool.db.sql.NamedSql;
@ -203,7 +203,7 @@ public class StatementUtil {
//null参数的类型缓存避免循环中重复获取类型
final Map<Integer, Integer> nullTypeMap = new HashMap<>();
for (final Entity entity : entities) {
fillParams(ps, CollUtil.valuesOfKeys(entity, fields), nullTypeMap);
fillParams(ps, MapUtil.valuesOfKeys(entity, fields), nullTypeMap);
ps.addBatch();
}
return ps;