mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-08-18 20:38:02 +08:00
Merge branch 'v6-dev' into refactor-stream
# Conflicts: # hutool-core/src/main/java/cn/hutool/core/stream/EasyStream.java # hutool-core/src/main/java/cn/hutool/core/stream/WrappedStream.java
This commit is contained in:
@@ -3,6 +3,7 @@ package cn.hutool.core.collection.iter;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 数组Iterator对象
|
||||
@@ -75,7 +76,7 @@ public class ArrayIter<E> implements IterableIter<E>, ResettableIter<E>, Seriali
|
||||
* @throws NullPointerException array对象为null
|
||||
*/
|
||||
public ArrayIter(final Object array, final int startIndex, final int endIndex) {
|
||||
this.endIndex = Array.getLength(array);
|
||||
this.endIndex = Array.getLength(Objects.requireNonNull(array));
|
||||
if (endIndex > 0 && endIndex < this.endIndex) {
|
||||
this.endIndex = endIndex;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package cn.hutool.core.collection.iter;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
@@ -39,12 +41,12 @@ public class CopiedIter<E> implements IterableIter<E>, Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
* 构造,当{@code iterator}为空时,默认复制一个空迭代器
|
||||
*
|
||||
* @param iterator 被复制的Iterator
|
||||
*/
|
||||
public CopiedIter(final Iterator<E> iterator) {
|
||||
final List<E> eleList = ListUtil.of(iterator);
|
||||
final List<E> eleList = ListUtil.of(ObjUtil.defaultIfNull(iterator, Collections.emptyIterator()));
|
||||
this.listIterator = eleList.iterator();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package cn.hutool.core.collection.iter;
|
||||
|
||||
import cn.hutool.core.collection.iter.IterableIter;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
|
||||
@@ -32,6 +32,7 @@ public class FilterIter<E> implements Iterator<E> {
|
||||
*
|
||||
* @param iterator 被包装的{@link Iterator}
|
||||
* @param filter 过滤函数,{@code null}表示不过滤
|
||||
* @throws NullPointerException {@code iterator}为{@code null}时抛出
|
||||
*/
|
||||
public FilterIter(final Iterator<? extends E> iterator, final Predicate<? super E> filter) {
|
||||
this.iterator = Assert.notNull(iterator);
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package cn.hutool.core.collection.iter;
|
||||
|
||||
import cn.hutool.core.lang.Chain;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 组合{@link Iterator},将多个{@link Iterator}组合在一起,便于集中遍历。<br>
|
||||
@@ -28,16 +26,27 @@ public class IterChain<T> implements Iterator<T>, Chain<Iterator<T>, IterChain<T
|
||||
/**
|
||||
* 构造
|
||||
* @param iterators 多个{@link Iterator}
|
||||
* @throws IllegalArgumentException 当存在重复的迭代器,或添加的迭代器中存在{@code null}时抛出
|
||||
*/
|
||||
@SafeVarargs
|
||||
public IterChain(final Iterator<T>... iterators) {
|
||||
for (final Iterator<T> iterator : iterators) {
|
||||
addChain(iterator);
|
||||
if (ArrayUtil.isNotEmpty(iterators)) {
|
||||
for (final Iterator<T> iterator : iterators) {
|
||||
addChain(iterator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加迭代器
|
||||
*
|
||||
* @param iterator 迭代器
|
||||
* @return 当前实例
|
||||
* @throws IllegalArgumentException 当迭代器被重复添加,或待添加的迭代器为{@code null}时抛出
|
||||
*/
|
||||
@Override
|
||||
public IterChain<T> addChain(final Iterator<T> iterator) {
|
||||
Objects.requireNonNull(iterator);
|
||||
if (allIterators.contains(iterator)) {
|
||||
throw new IllegalArgumentException("Duplicate iterator");
|
||||
}
|
||||
|
||||
@@ -11,16 +11,7 @@ import cn.hutool.core.util.ObjUtil;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Dictionary;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
@@ -192,32 +183,35 @@ public class IterUtil {
|
||||
/**
|
||||
* 获取指定Bean列表中某个字段,生成新的列表
|
||||
*
|
||||
* @param <R> 返回元素类型
|
||||
* @param <V> 对象类型
|
||||
* @param iterable 对象列表
|
||||
* @param fieldName 字段名(会通过反射获取其值)
|
||||
* @return 某个字段值与对象对应Map
|
||||
* @since 4.6.2
|
||||
*/
|
||||
public static <V> List<Object> fieldValueList(final Iterable<V> iterable, final String fieldName) {
|
||||
public static <V, R> List<R> fieldValueList(final Iterable<V> iterable, final String fieldName) {
|
||||
return fieldValueList(getIter(iterable), fieldName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定Bean列表中某个字段,生成新的列表
|
||||
*
|
||||
* @param <R> 返回元素类型
|
||||
* @param <V> 对象类型
|
||||
* @param iter 对象列表
|
||||
* @param fieldName 字段名(会通过反射获取其值)
|
||||
* @return 某个字段值与对象对应Map
|
||||
* @since 4.0.10
|
||||
*/
|
||||
public static <V> List<Object> fieldValueList(final Iterator<V> iter, final String fieldName) {
|
||||
final List<Object> result = new ArrayList<>();
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <V, R> List<R> fieldValueList(final Iterator<V> iter, final String fieldName) {
|
||||
final List<R> result = new ArrayList<>();
|
||||
if (null != iter) {
|
||||
V value;
|
||||
while (iter.hasNext()) {
|
||||
value = iter.next();
|
||||
result.add(FieldUtil.getFieldValue(value, fieldName));
|
||||
result.add((R)FieldUtil.getFieldValue(value, fieldName));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -378,7 +372,7 @@ public class IterUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 将列表转成值为List的HashMap
|
||||
* 将列表转成值为List的Map集合
|
||||
*
|
||||
* @param resultMap 结果Map,可自定义结果Map类型
|
||||
* @param iterable 值列表
|
||||
@@ -702,38 +696,40 @@ public class IterUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断两个{@link Iterable} 是否元素和顺序相同,返回{@code true}的条件是:
|
||||
* <p>判断两个{@link Iterable}中的元素与其顺序是否相同 <br>
|
||||
* 当满足下列情况时返回{@code true}:
|
||||
* <ul>
|
||||
* <li>两个{@link Iterable}必须长度相同</li>
|
||||
* <li>两个{@link Iterable}元素相同index的对象必须equals,满足{@link Objects#equals(Object, Object)}</li>
|
||||
* <li>两个{@link Iterable}都为{@code null};</li>
|
||||
* <li>两个{@link Iterable}满足{@code iterable1 == iterable2};</li>
|
||||
* <li>两个{@link Iterable}所有具有相同下标的元素皆满足{@link Objects#equals(Object, Object)};</li>
|
||||
* </ul>
|
||||
* 此方法来自Apache-Commons-Collections4。
|
||||
*
|
||||
* @param list1 列表1
|
||||
* @param list2 列表2
|
||||
* @param iterable1 列表1
|
||||
* @param iterable2 列表2
|
||||
* @return 是否相同
|
||||
* @since 5.6.0
|
||||
*/
|
||||
public static boolean isEqualList(final Iterable<?> list1, final Iterable<?> list2) {
|
||||
if (list1 == list2) {
|
||||
public static boolean isEqualList(final Iterable<?> iterable1, final Iterable<?> iterable2) {
|
||||
if (iterable1 == iterable2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final Iterator<?> it1 = list1.iterator();
|
||||
final Iterator<?> it2 = list2.iterator();
|
||||
if (iterable1 == null || iterable2 == null) {
|
||||
return false;
|
||||
}
|
||||
final Iterator<?> iter1 = iterable1.iterator();
|
||||
final Iterator<?> iter2 = iterable2.iterator();
|
||||
Object obj1;
|
||||
Object obj2;
|
||||
while (it1.hasNext() && it2.hasNext()) {
|
||||
obj1 = it1.next();
|
||||
obj2 = it2.next();
|
||||
|
||||
while (iter1.hasNext() && iter2.hasNext()) {
|
||||
obj1 = iter1.next();
|
||||
obj2 = iter2.next();
|
||||
if (false == Objects.equals(obj1, obj2)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 当两个Iterable长度不一致时返回false
|
||||
return false == (it1.hasNext() || it2.hasNext());
|
||||
return false == (iter1.hasNext() || iter2.hasNext());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,4 +15,5 @@ public interface IterableIter<T> extends Iterable<T>, Iterator<T> {
|
||||
default Iterator<T> iterator() {
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ public class IteratorEnumeration<E> implements Enumeration<E>, Serializable{
|
||||
|
||||
private final Iterator<E> iterator;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 构造
|
||||
* @param iterator {@link Iterator}对象
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package cn.hutool.core.collection.iter;
|
||||
|
||||
import cn.hutool.core.collection.iter.IterableIter;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 分批迭代工具,可以分批处理数据
|
||||
@@ -36,9 +37,11 @@ public class PartitionIter<T> implements IterableIter<List<T>>, Serializable {
|
||||
*
|
||||
* @param iterator 迭代器
|
||||
* @param partitionSize 每批大小,最后一批不满一批算一批
|
||||
* @throws IllegalArgumentException 当{@code partitionSize}小于等于0,或{@code iterator}为{@code null}时抛出
|
||||
*/
|
||||
public PartitionIter(final Iterator<T> iterator, final int partitionSize) {
|
||||
this.iterator = iterator;
|
||||
Assert.isTrue(partitionSize > 0, "partition size must greater than 0");
|
||||
this.iterator = Objects.requireNonNull(iterator);
|
||||
this.partitionSize = partitionSize;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package cn.hutool.core.collection.partition;
|
||||
|
||||
import cn.hutool.core.collection.partition.Partition;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -164,7 +164,7 @@ public class ZipWriter implements Closeable {
|
||||
* @throws IORuntimeException IO异常
|
||||
*/
|
||||
public ZipWriter add(String path, final InputStream in) throws IORuntimeException {
|
||||
path = StrUtil.nullToEmpty(path);
|
||||
path = StrUtil.emptyIfNull(path);
|
||||
if (null == in) {
|
||||
// 空目录需要检查路径规范性,目录以"/"结尾
|
||||
path = StrUtil.addSuffixIfNot(path, StrUtil.SLASH);
|
||||
|
||||
@@ -783,11 +783,7 @@ public class DateTime extends Date {
|
||||
* @since 3.0.8
|
||||
*/
|
||||
public boolean isIn(final Date beginDate, final Date endDate) {
|
||||
final long beginMills = beginDate.getTime();
|
||||
final long endMills = endDate.getTime();
|
||||
final long thisMills = this.getTime();
|
||||
|
||||
return thisMills >= Math.min(beginMills, endMills) && thisMills <= Math.max(beginMills, endMills);
|
||||
return DateUtil.isIn(this, beginDate, endDate);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1381,11 +1381,49 @@ public class DateUtil extends CalendarUtil {
|
||||
* @since 3.0.8
|
||||
*/
|
||||
public static boolean isIn(final Date date, final Date beginDate, final Date endDate) {
|
||||
if (date instanceof DateTime) {
|
||||
return ((DateTime) date).isIn(beginDate, endDate);
|
||||
} else {
|
||||
return new DateTime(date).isIn(beginDate, endDate);
|
||||
return isIn(date, beginDate, endDate, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前日期是否在日期指定范围内<br>
|
||||
* 起始日期和结束日期可以互换<br>
|
||||
* 通过includeBegin, includeEnd参数控制日期范围区间是否为开区间,例如:传入参数:includeBegin=true, includeEnd=false,
|
||||
* 则本方法会判断 date ∈ (beginDate, endDate] 是否成立
|
||||
*
|
||||
* @param date 被检查的日期
|
||||
* @param beginDate 起始日期
|
||||
* @param endDate 结束日期
|
||||
* @param includeBegin 时间范围是否包含起始日期
|
||||
* @param includeEnd 时间范围是否包含结束日期
|
||||
* @return 是否在范围内
|
||||
* @author FengBaoheng
|
||||
* @since 5.8.6
|
||||
*/
|
||||
public static boolean isIn(final Date date, final Date beginDate, final Date endDate,
|
||||
final boolean includeBegin, final boolean includeEnd) {
|
||||
if (date == null || beginDate == null || endDate == null) {
|
||||
throw new IllegalArgumentException("参数不可为null");
|
||||
}
|
||||
|
||||
final long thisMills = date.getTime();
|
||||
final long beginMills = beginDate.getTime();
|
||||
final long endMills = endDate.getTime();
|
||||
final long rangeMin = Math.min(beginMills, endMills);
|
||||
final long rangeMax = Math.max(beginMills, endMills);
|
||||
|
||||
// 先判断是否满足 date ∈ (beginDate, endDate)
|
||||
boolean isIn = rangeMin < thisMills && thisMills < rangeMax;
|
||||
|
||||
// 若不满足,则再判断是否在时间范围的边界上
|
||||
if (false == isIn && includeBegin) {
|
||||
isIn = thisMills == rangeMin;
|
||||
}
|
||||
|
||||
if (false == isIn && includeEnd) {
|
||||
isIn = thisMills == rangeMax;
|
||||
}
|
||||
|
||||
return isIn;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -181,11 +181,49 @@ public class TemporalAccessorUtil extends TemporalUtil{
|
||||
* @param endDate 结束日期(包含)
|
||||
* @return 是否在范围内
|
||||
*/
|
||||
public static boolean isIn(TemporalAccessor date, TemporalAccessor beginDate, TemporalAccessor endDate){
|
||||
final long thisMills = TemporalAccessorUtil.toEpochMilli(date);
|
||||
final long beginMills = TemporalAccessorUtil.toEpochMilli(beginDate);
|
||||
final long endMills = TemporalAccessorUtil.toEpochMilli(endDate);
|
||||
public static boolean isIn(final TemporalAccessor date, final TemporalAccessor beginDate, final TemporalAccessor endDate){
|
||||
return isIn(date, beginDate, endDate, true, true);
|
||||
}
|
||||
|
||||
return thisMills >= Math.min(beginMills, endMills) && thisMills <= Math.max(beginMills, endMills);
|
||||
/**
|
||||
* 当前日期是否在日期指定范围内<br>
|
||||
* 起始日期和结束日期可以互换<br>
|
||||
* 通过includeBegin, includeEnd参数控制日期范围区间是否为开区间,例如:传入参数:includeBegin=true, includeEnd=false,
|
||||
* 则本方法会判断 date ∈ (beginDate, endDate] 是否成立
|
||||
*
|
||||
* @param date 被检查的日期
|
||||
* @param beginDate 起始日期
|
||||
* @param endDate 结束日期
|
||||
* @param includeBegin 时间范围是否包含起始日期
|
||||
* @param includeEnd 时间范围是否包含结束日期
|
||||
* @return 是否在范围内
|
||||
* @author FengBaoheng
|
||||
* @since 5.8.6
|
||||
*/
|
||||
public static boolean isIn(final TemporalAccessor date, final TemporalAccessor beginDate, final TemporalAccessor endDate,
|
||||
final boolean includeBegin, final boolean includeEnd) {
|
||||
if (date == null || beginDate == null || endDate == null) {
|
||||
throw new IllegalArgumentException("参数不可为null");
|
||||
}
|
||||
|
||||
final long thisMills = toEpochMilli(date);
|
||||
final long beginMills = toEpochMilli(beginDate);
|
||||
final long endMills = toEpochMilli(endDate);
|
||||
final long rangeMin = Math.min(beginMills, endMills);
|
||||
final long rangeMax = Math.max(beginMills, endMills);
|
||||
|
||||
// 先判断是否满足 date ∈ (beginDate, endDate)
|
||||
boolean isIn = rangeMin < thisMills && thisMills < rangeMax;
|
||||
|
||||
// 若不满足,则再判断是否在时间范围的边界上
|
||||
if (false == isIn && includeBegin) {
|
||||
isIn = thisMills == rangeMin;
|
||||
}
|
||||
|
||||
if (false == isIn && includeEnd) {
|
||||
isIn = thisMills == rangeMax;
|
||||
}
|
||||
|
||||
return isIn;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ public class ResourceUtil {
|
||||
* @return {@link URL}
|
||||
*/
|
||||
public static URL getResourceUrl(String resource, final Class<?> baseClass) {
|
||||
resource = StrUtil.nullToEmpty(resource);
|
||||
resource = StrUtil.emptyIfNull(resource);
|
||||
return (null != baseClass) ? baseClass.getResource(resource) : ClassLoaderUtil.getClassLoader().getResource(resource);
|
||||
}
|
||||
|
||||
|
||||
@@ -209,7 +209,7 @@ public class ClassScanner implements Serializable {
|
||||
* @param charset 编码
|
||||
*/
|
||||
public ClassScanner(String packageName, final Predicate<Class<?>> classPredicate, final Charset charset) {
|
||||
packageName = StrUtil.nullToEmpty(packageName);
|
||||
packageName = StrUtil.emptyIfNull(packageName);
|
||||
this.packageName = packageName;
|
||||
this.packageNameWithDot = StrUtil.addSuffixIfNot(packageName, StrUtil.DOT);
|
||||
this.packageDirName = packageName.replace(CharUtil.DOT, File.separatorChar);
|
||||
|
||||
328
hutool-core/src/main/java/cn/hutool/core/map/MapGetUtil.java
Executable file
328
hutool-core/src/main/java/cn/hutool/core/map/MapGetUtil.java
Executable file
@@ -0,0 +1,328 @@
|
||||
package cn.hutool.core.map;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.reflect.TypeReference;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Map的getXXX封装,提供针对通用型的value按照所需类型获取值
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class MapGetUtil {
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为字符串
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @return 值
|
||||
* @since 4.0.6
|
||||
*/
|
||||
public static String getStr(final Map<?, ?> map, final Object key) {
|
||||
return get(map, key, String.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为字符串
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public static String getStr(final Map<?, ?> map, final Object key, final String defaultValue) {
|
||||
return get(map, key, String.class, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Integer
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @return 值
|
||||
* @since 4.0.6
|
||||
*/
|
||||
public static Integer getInt(final Map<?, ?> map, final Object key) {
|
||||
return get(map, key, Integer.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Integer
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public static Integer getInt(final Map<?, ?> map, final Object key, final Integer defaultValue) {
|
||||
return get(map, key, Integer.class, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Double
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @return 值
|
||||
* @since 4.0.6
|
||||
*/
|
||||
public static Double getDouble(final Map<?, ?> map, final Object key) {
|
||||
return get(map, key, Double.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Double
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public static Double getDouble(final Map<?, ?> map, final Object key, final Double defaultValue) {
|
||||
return get(map, key, Double.class, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Float
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @return 值
|
||||
* @since 4.0.6
|
||||
*/
|
||||
public static Float getFloat(final Map<?, ?> map, final Object key) {
|
||||
return get(map, key, Float.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Float
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public static Float getFloat(final Map<?, ?> map, final Object key, final Float defaultValue) {
|
||||
return get(map, key, Float.class, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Short
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @return 值
|
||||
* @since 4.0.6
|
||||
*/
|
||||
public static Short getShort(final Map<?, ?> map, final Object key) {
|
||||
return get(map, key, Short.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Short
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public static Short getShort(final Map<?, ?> map, final Object key, final Short defaultValue) {
|
||||
return get(map, key, Short.class, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Bool
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @return 值
|
||||
* @since 4.0.6
|
||||
*/
|
||||
public static Boolean getBool(final Map<?, ?> map, final Object key) {
|
||||
return get(map, key, Boolean.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Bool
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public static Boolean getBool(final Map<?, ?> map, final Object key, final Boolean defaultValue) {
|
||||
return get(map, key, Boolean.class, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Character
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @return 值
|
||||
* @since 4.0.6
|
||||
*/
|
||||
public static Character getChar(final Map<?, ?> map, final Object key) {
|
||||
return get(map, key, Character.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Character
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public static Character getChar(final Map<?, ?> map, final Object key, final Character defaultValue) {
|
||||
return get(map, key, Character.class, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Long
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @return 值
|
||||
* @since 4.0.6
|
||||
*/
|
||||
public static Long getLong(final Map<?, ?> map, final Object key) {
|
||||
return get(map, key, Long.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Long
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public static Long getLong(final Map<?, ?> map, final Object key, final Long defaultValue) {
|
||||
return get(map, key, Long.class, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为{@link Date}
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @return 值
|
||||
* @since 4.1.2
|
||||
*/
|
||||
public static Date getDate(final Map<?, ?> map, final Object key) {
|
||||
return get(map, key, Date.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为{@link Date}
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 4.1.2
|
||||
*/
|
||||
public static Date getDate(final Map<?, ?> map, final Object key, final Date defaultValue) {
|
||||
return get(map, key, Date.class, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为指定类型
|
||||
*
|
||||
* @param <T> 目标值类型
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param type 值类型
|
||||
* @return 值
|
||||
* @since 4.0.6
|
||||
*/
|
||||
public static <T> T get(final Map<?, ?> map, final Object key, final Class<T> type) {
|
||||
return get(map, key, type, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为指定类型
|
||||
*
|
||||
* @param <T> 目标值类型
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param type 值类型
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public static <T> T get(final Map<?, ?> map, final Object key, final Class<T> type, final T defaultValue) {
|
||||
return null == map ? defaultValue : Convert.convert(type, map.get(key), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为指定类型,此方法在转换失败后不抛异常,返回null。
|
||||
*
|
||||
* @param <T> 目标值类型
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param type 值类型
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 5.5.3
|
||||
*/
|
||||
public static <T> T getQuietly(final Map<?, ?> map, final Object key, final Class<T> type, final T defaultValue) {
|
||||
return null == map ? defaultValue : Convert.convertQuietly(type, map.get(key), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为指定类型
|
||||
*
|
||||
* @param <T> 目标值类型
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param type 值类型
|
||||
* @return 值
|
||||
* @since 4.5.12
|
||||
*/
|
||||
public static <T> T get(final Map<?, ?> map, final Object key, final TypeReference<T> type) {
|
||||
return get(map, key, type, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为指定类型
|
||||
*
|
||||
* @param <T> 目标值类型
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param type 值类型
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public static <T> T get(final Map<?, ?> map, final Object key, final TypeReference<T> type, final T defaultValue) {
|
||||
return null == map ? defaultValue : Convert.convert(type, map.get(key), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为指定类型,转换失败后返回null,不抛异常
|
||||
*
|
||||
* @param <T> 目标值类型
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param type 值类型
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 5.5.3
|
||||
*/
|
||||
public static <T> T getQuietly(final Map<?, ?> map, final Object key, final TypeReference<T> type, final T defaultValue) {
|
||||
return null == map ? defaultValue : Convert.convertQuietly(type, map.get(key), defaultValue);
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ import cn.hutool.core.collection.iter.IterUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.exceptions.UtilException;
|
||||
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;
|
||||
@@ -16,7 +15,6 @@ import java.util.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Iterator;
|
||||
@@ -25,7 +23,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.NavigableMap;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -41,7 +38,7 @@ import java.util.stream.Collectors;
|
||||
* @author Looly
|
||||
* @since 3.1.1
|
||||
*/
|
||||
public class MapUtil {
|
||||
public class MapUtil extends MapGetUtil {
|
||||
|
||||
/**
|
||||
* 默认初始大小
|
||||
@@ -250,9 +247,9 @@ public class MapUtil {
|
||||
if (null == mapType || mapType.isAssignableFrom(AbstractMap.class)) {
|
||||
return new HashMap<>();
|
||||
} else {
|
||||
try{
|
||||
try {
|
||||
return (Map<K, V>) ConstructorUtil.newInstance(mapType);
|
||||
}catch (UtilException e){
|
||||
} catch (final UtilException e) {
|
||||
// 不支持的map类型,返回默认的HashMap
|
||||
return new HashMap<>();
|
||||
}
|
||||
@@ -483,14 +480,14 @@ public class MapUtil {
|
||||
}
|
||||
|
||||
final List<Map<K, V>> resultList = new ArrayList<>();
|
||||
for (Entry<K, ? extends Iterable<V>> entry : listMap.entrySet()) {
|
||||
for (final 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) {
|
||||
for (final Map<K, V> map : resultList) {
|
||||
// 还可以继续添加元素
|
||||
if (iterator.hasNext()) {
|
||||
map.put(key, iterator.next());
|
||||
@@ -966,319 +963,6 @@ public class MapUtil {
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为字符串
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @return 值
|
||||
* @since 4.0.6
|
||||
*/
|
||||
public static String getStr(final Map<?, ?> map, final Object key) {
|
||||
return get(map, key, String.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为字符串
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public static String getStr(final Map<?, ?> map, final Object key, final String defaultValue) {
|
||||
return get(map, key, String.class, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Integer
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @return 值
|
||||
* @since 4.0.6
|
||||
*/
|
||||
public static Integer getInt(final Map<?, ?> map, final Object key) {
|
||||
return get(map, key, Integer.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Integer
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public static Integer getInt(final Map<?, ?> map, final Object key, final Integer defaultValue) {
|
||||
return get(map, key, Integer.class, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Double
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @return 值
|
||||
* @since 4.0.6
|
||||
*/
|
||||
public static Double getDouble(final Map<?, ?> map, final Object key) {
|
||||
return get(map, key, Double.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Double
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public static Double getDouble(final Map<?, ?> map, final Object key, final Double defaultValue) {
|
||||
return get(map, key, Double.class, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Float
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @return 值
|
||||
* @since 4.0.6
|
||||
*/
|
||||
public static Float getFloat(final Map<?, ?> map, final Object key) {
|
||||
return get(map, key, Float.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Float
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public static Float getFloat(final Map<?, ?> map, final Object key, final Float defaultValue) {
|
||||
return get(map, key, Float.class, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Short
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @return 值
|
||||
* @since 4.0.6
|
||||
*/
|
||||
public static Short getShort(final Map<?, ?> map, final Object key) {
|
||||
return get(map, key, Short.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Short
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public static Short getShort(final Map<?, ?> map, final Object key, final Short defaultValue) {
|
||||
return get(map, key, Short.class, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Bool
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @return 值
|
||||
* @since 4.0.6
|
||||
*/
|
||||
public static Boolean getBool(final Map<?, ?> map, final Object key) {
|
||||
return get(map, key, Boolean.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Bool
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public static Boolean getBool(final Map<?, ?> map, final Object key, final Boolean defaultValue) {
|
||||
return get(map, key, Boolean.class, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Character
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @return 值
|
||||
* @since 4.0.6
|
||||
*/
|
||||
public static Character getChar(final Map<?, ?> map, final Object key) {
|
||||
return get(map, key, Character.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Character
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public static Character getChar(final Map<?, ?> map, final Object key, final Character defaultValue) {
|
||||
return get(map, key, Character.class, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Long
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @return 值
|
||||
* @since 4.0.6
|
||||
*/
|
||||
public static Long getLong(final Map<?, ?> map, final Object key) {
|
||||
return get(map, key, Long.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为Long
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public static Long getLong(final Map<?, ?> map, final Object key, final Long defaultValue) {
|
||||
return get(map, key, Long.class, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为{@link Date}
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @return 值
|
||||
* @since 4.1.2
|
||||
*/
|
||||
public static Date getDate(final Map<?, ?> map, final Object key) {
|
||||
return get(map, key, Date.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为{@link Date}
|
||||
*
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 4.1.2
|
||||
*/
|
||||
public static Date getDate(final Map<?, ?> map, final Object key, final Date defaultValue) {
|
||||
return get(map, key, Date.class, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为指定类型
|
||||
*
|
||||
* @param <T> 目标值类型
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param type 值类型
|
||||
* @return 值
|
||||
* @since 4.0.6
|
||||
*/
|
||||
public static <T> T get(final Map<?, ?> map, final Object key, final Class<T> type) {
|
||||
return get(map, key, type, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为指定类型
|
||||
*
|
||||
* @param <T> 目标值类型
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param type 值类型
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public static <T> T get(final Map<?, ?> map, final Object key, final Class<T> type, final T defaultValue) {
|
||||
return null == map ? defaultValue : Convert.convert(type, map.get(key), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为指定类型,此方法在转换失败后不抛异常,返回null。
|
||||
*
|
||||
* @param <T> 目标值类型
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param type 值类型
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 5.5.3
|
||||
*/
|
||||
public static <T> T getQuietly(final Map<?, ?> map, final Object key, final Class<T> type, final T defaultValue) {
|
||||
return null == map ? defaultValue : Convert.convertQuietly(type, map.get(key), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为指定类型
|
||||
*
|
||||
* @param <T> 目标值类型
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param type 值类型
|
||||
* @return 值
|
||||
* @since 4.5.12
|
||||
*/
|
||||
public static <T> T get(final Map<?, ?> map, final Object key, final TypeReference<T> type) {
|
||||
return get(map, key, type, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为指定类型
|
||||
*
|
||||
* @param <T> 目标值类型
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param type 值类型
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public static <T> T get(final Map<?, ?> map, final Object key, final TypeReference<T> type, final T defaultValue) {
|
||||
return null == map ? defaultValue : Convert.convert(type, map.get(key), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map指定key的值,并转换为指定类型,转换失败后返回null,不抛异常
|
||||
*
|
||||
* @param <T> 目标值类型
|
||||
* @param map Map
|
||||
* @param key 键
|
||||
* @param type 值类型
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
* @since 5.5.3
|
||||
*/
|
||||
public static <T> T getQuietly(final Map<?, ?> map, final Object key, final TypeReference<T> type, final T defaultValue) {
|
||||
return null == map ? defaultValue : Convert.convertQuietly(type, map.get(key), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重命名键<br>
|
||||
* 实现方式为一处然后重新put,当旧的key不存在直接返回<br>
|
||||
@@ -1557,4 +1241,32 @@ public class MapUtil {
|
||||
}
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据给定的entry列表,根据entry的key进行分组;
|
||||
*
|
||||
* @param <K> 键类型
|
||||
* @param <V> 值类型
|
||||
* @param entries entry列表
|
||||
* @return entries
|
||||
* @since 5.8.6
|
||||
*/
|
||||
public static <K, V> Map<K, List<V>> grouping(final Iterable<Map.Entry<K, V>> entries) {
|
||||
if (CollUtil.isEmpty(entries)) {
|
||||
return zero();
|
||||
}
|
||||
|
||||
final Map<K, List<V>> map = new HashMap<>();
|
||||
for (final Map.Entry<K, V> pair : entries) {
|
||||
final List<V> values;
|
||||
if (map.containsKey(pair.getKey())) {
|
||||
values = map.get(pair.getKey());
|
||||
} else {
|
||||
values = ListUtil.of();
|
||||
map.put(pair.getKey(), values);
|
||||
}
|
||||
values.add(pair.getValue());
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -579,7 +579,7 @@ public class URLUtil {
|
||||
if (isEncodePath) {
|
||||
path = RFC3986.PATH.encode(path, CharsetUtil.UTF_8);
|
||||
}
|
||||
return protocol + domain + StrUtil.nullToEmpty(path) + StrUtil.nullToEmpty(params);
|
||||
return protocol + domain + StrUtil.emptyIfNull(path) + StrUtil.emptyIfNull(params);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -406,7 +406,7 @@ public class UrlQuery {
|
||||
private void addParam(final String key, final String value, final Charset charset) {
|
||||
if (null != key) {
|
||||
final String actualKey = URLDecoder.decode(key, charset, isFormUrlEncoded);
|
||||
this.query.put(actualKey, StrUtil.nullToEmpty(URLDecoder.decode(value, charset, isFormUrlEncoded)));
|
||||
this.query.put(actualKey, StrUtil.emptyIfNull(URLDecoder.decode(value, charset, isFormUrlEncoded)));
|
||||
} else if (null != value) {
|
||||
// name为空,value作为name,value赋值null
|
||||
this.query.put(URLDecoder.decode(value, charset, isFormUrlEncoded), null);
|
||||
|
||||
@@ -26,7 +26,7 @@ public class CollectorUtil {
|
||||
* 说明已包含IDENTITY_FINISH特征 为 Characteristics.IDENTITY_FINISH 的缩写
|
||||
*/
|
||||
public static final Set<Collector.Characteristics> CH_ID
|
||||
= Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH));
|
||||
= Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH));
|
||||
/**
|
||||
* 说明不包含IDENTITY_FINISH特征
|
||||
*/
|
||||
@@ -52,7 +52,7 @@ public class CollectorUtil {
|
||||
* @return {@link Collector}
|
||||
*/
|
||||
public static <T> Collector<T, ?, String> joining(final CharSequence delimiter,
|
||||
final Function<T, ? extends CharSequence> toStringFunc) {
|
||||
final Function<T, ? extends CharSequence> toStringFunc) {
|
||||
return joining(delimiter, StrUtil.EMPTY, StrUtil.EMPTY, toStringFunc);
|
||||
}
|
||||
|
||||
@@ -67,15 +67,15 @@ public class CollectorUtil {
|
||||
* @return {@link Collector}
|
||||
*/
|
||||
public static <T> Collector<T, ?, String> joining(final CharSequence delimiter,
|
||||
final CharSequence prefix,
|
||||
final CharSequence suffix,
|
||||
final Function<T, ? extends CharSequence> toStringFunc) {
|
||||
final CharSequence prefix,
|
||||
final CharSequence suffix,
|
||||
final Function<T, ? extends CharSequence> toStringFunc) {
|
||||
return new SimpleCollector<>(
|
||||
() -> new StringJoiner(delimiter, prefix, suffix),
|
||||
(joiner, ele) -> joiner.add(toStringFunc.apply(ele)),
|
||||
StringJoiner::merge,
|
||||
StringJoiner::toString,
|
||||
Collections.emptySet()
|
||||
() -> new StringJoiner(delimiter, prefix, suffix),
|
||||
(joiner, ele) -> joiner.add(toStringFunc.apply(ele)),
|
||||
StringJoiner::merge,
|
||||
StringJoiner::toString,
|
||||
Collections.emptySet()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -94,8 +94,8 @@ public class CollectorUtil {
|
||||
* @return {@link Collector}
|
||||
*/
|
||||
public static <T, K, D, A, M extends Map<K, D>> Collector<T, ?, M> groupingBy(final Function<? super T, ? extends K> classifier,
|
||||
final Supplier<M> mapFactory,
|
||||
final Collector<? super T, A, D> downstream) {
|
||||
final Supplier<M> mapFactory,
|
||||
final Collector<? super T, A, D> downstream) {
|
||||
final Supplier<A> downstreamSupplier = downstream.supplier();
|
||||
final BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
|
||||
final BiConsumer<Map<K, A>, T> accumulator = (m, t) -> {
|
||||
@@ -133,9 +133,8 @@ public class CollectorUtil {
|
||||
* @param <A> 下游操作在进行中间操作时对应类型
|
||||
* @return {@link Collector}
|
||||
*/
|
||||
public static <T, K, A, D>
|
||||
Collector<T, ?, Map<K, D>> groupingBy(final Function<? super T, ? extends K> classifier,
|
||||
final Collector<? super T, A, D> downstream) {
|
||||
public static <T, K, A, D> Collector<T, ?, Map<K, D>> groupingBy(final Function<? super T, ? extends K> classifier,
|
||||
final Collector<? super T, A, D> downstream) {
|
||||
return groupingBy(classifier, HashMap::new, downstream);
|
||||
}
|
||||
|
||||
@@ -147,8 +146,7 @@ public class CollectorUtil {
|
||||
* @param <K> 实体中的分组依据对应类型,也是Map中key的类型
|
||||
* @return {@link Collector}
|
||||
*/
|
||||
public static <T, K> Collector<T, ?, Map<K, List<T>>>
|
||||
groupingBy(final Function<? super T, ? extends K> classifier) {
|
||||
public static <T, K> Collector<T, ?, Map<K, List<T>>> groupingBy(final Function<? super T, ? extends K> classifier) {
|
||||
return groupingBy(classifier, Collectors.toList());
|
||||
}
|
||||
|
||||
@@ -163,10 +161,9 @@ public class CollectorUtil {
|
||||
* @param <U> map中value的类型
|
||||
* @return 对null友好的 toMap 操作的 {@link Collector}实现
|
||||
*/
|
||||
public static <T, K, U>
|
||||
Collector<T, ?, Map<K, U>> toMap(final Function<? super T, ? extends K> keyMapper,
|
||||
final Function<? super T, ? extends U> valueMapper,
|
||||
final BinaryOperator<U> mergeFunction) {
|
||||
public static <T, K, U> Collector<T, ?, Map<K, U>> toMap(final Function<? super T, ? extends K> keyMapper,
|
||||
final Function<? super T, ? extends U> valueMapper,
|
||||
final BinaryOperator<U> mergeFunction) {
|
||||
return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
|
||||
}
|
||||
|
||||
@@ -185,11 +182,11 @@ public class CollectorUtil {
|
||||
*/
|
||||
public static <T, K, U, M extends Map<K, U>>
|
||||
Collector<T, ?, M> toMap(final Function<? super T, ? extends K> keyMapper,
|
||||
final Function<? super T, ? extends U> valueMapper,
|
||||
final BinaryOperator<U> mergeFunction,
|
||||
final Supplier<M> mapSupplier) {
|
||||
final Function<? super T, ? extends U> valueMapper,
|
||||
final BinaryOperator<U> mergeFunction,
|
||||
final Supplier<M> mapSupplier) {
|
||||
final BiConsumer<M, T> accumulator
|
||||
= (map, element) -> map.put(Opt.ofNullable(element).map(keyMapper).get(), Opt.ofNullable(element).map(valueMapper).get());
|
||||
= (map, element) -> map.put(Opt.ofNullable(element).map(keyMapper).get(), Opt.ofNullable(element).map(valueMapper).get());
|
||||
return new SimpleCollector<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID);
|
||||
}
|
||||
|
||||
@@ -235,13 +232,13 @@ public class CollectorUtil {
|
||||
*/
|
||||
public static <K, V, R extends Map<K, List<V>>> Collector<Map<K, V>, ?, R> reduceListMap(final Supplier<R> mapSupplier) {
|
||||
return Collectors.reducing(mapSupplier.get(), value -> {
|
||||
R result = mapSupplier.get();
|
||||
value.forEach((k, v) -> result.computeIfAbsent(k, i -> new ArrayList<>()).add(v));
|
||||
return result;
|
||||
}, (l, r) -> {
|
||||
r.forEach((k, v) -> l.computeIfAbsent(k, i -> new ArrayList<>()).addAll(v));
|
||||
return l;
|
||||
}
|
||||
final R result = mapSupplier.get();
|
||||
value.forEach((k, v) -> result.computeIfAbsent(k, i -> new ArrayList<>()).add(v));
|
||||
return result;
|
||||
}, (l, r) -> {
|
||||
r.forEach((k, v) -> l.computeIfAbsent(k, i -> new ArrayList<>()).addAll(v));
|
||||
return l;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -271,7 +268,7 @@ public class CollectorUtil {
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public static <T, K, V> Collector<T, List<T>, EntryStream<K, V>> toEntryStream(
|
||||
Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends V> valueMapper) {
|
||||
final Function<? super T, ? extends K> keyMapper, final Function<? super T, ? extends V> valueMapper) {
|
||||
Objects.requireNonNull(keyMapper);
|
||||
Objects.requireNonNull(valueMapper);
|
||||
return transform(ArrayList::new, list -> EntryStream.of(list, keyMapper, valueMapper));
|
||||
@@ -306,11 +303,14 @@ public class CollectorUtil {
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public static <T, R, C extends Collection<T>> Collector<T, C, R> transform(
|
||||
Supplier<C> collFactory, Function<C, R> mapper) {
|
||||
final Supplier<C> collFactory, final Function<C, R> mapper) {
|
||||
Objects.requireNonNull(collFactory);
|
||||
Objects.requireNonNull(mapper);
|
||||
return new SimpleCollector<>(
|
||||
collFactory, C::add, (l1, l2) -> { l1.addAll(l2); return l1; }, mapper, CH_NOID
|
||||
collFactory, C::add, (l1, l2) -> {
|
||||
l1.addAll(l2);
|
||||
return l1;
|
||||
}, mapper, CH_NOID
|
||||
);
|
||||
}
|
||||
|
||||
@@ -329,7 +329,7 @@ public class CollectorUtil {
|
||||
* @return 收集器
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public static <T, R> Collector<T, List<T>, R> transform(Function<List<T>, R> mapper) {
|
||||
public static <T, R> Collector<T, List<T>, R> transform(final Function<List<T>, R> mapper) {
|
||||
return transform(ArrayList::new, mapper);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ public class CharSequenceUtil extends StrChecker {
|
||||
* @param str 被转换的字符串
|
||||
* @return 转换后的字符串
|
||||
*/
|
||||
public static String nullToEmpty(final CharSequence str) {
|
||||
public static String emptyIfNull(final CharSequence str) {
|
||||
return ObjUtil.defaultIfNull(str, EMPTY).toString();
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ public class CharSequenceUtil extends StrChecker {
|
||||
* @param str 被转换的字符串
|
||||
* @return 转换后的字符串
|
||||
*/
|
||||
public static <T extends CharSequence> T emptyToNull(final T str) {
|
||||
public static <T extends CharSequence> T nullIfEmpty(final T str) {
|
||||
return isEmpty(str) ? null : str;
|
||||
}
|
||||
|
||||
@@ -809,10 +809,10 @@ public class CharSequenceUtil extends StrChecker {
|
||||
/**
|
||||
* 指定范围内查找指定字符
|
||||
*
|
||||
* @param text 字符串
|
||||
* @param matcher 被查找的字符匹配器
|
||||
* @param start 起始位置,如果小于0,从0开始查找
|
||||
* @param end 终止位置,如果超过str.length()则默认查找到字符串末尾
|
||||
* @param text 字符串
|
||||
* @param matcher 被查找的字符匹配器
|
||||
* @param start 起始位置,如果小于0,从0开始查找
|
||||
* @param end 终止位置,如果超过str.length()则默认查找到字符串末尾
|
||||
* @return 位置
|
||||
* @since 6.0.0
|
||||
*/
|
||||
@@ -2521,7 +2521,7 @@ public class CharSequenceUtil extends StrChecker {
|
||||
* @return 包装后的字符串
|
||||
*/
|
||||
public static String wrap(final CharSequence str, final CharSequence prefix, final CharSequence suffix) {
|
||||
return nullToEmpty(prefix).concat(nullToEmpty(str)).concat(nullToEmpty(suffix));
|
||||
return emptyIfNull(prefix).concat(emptyIfNull(str)).concat(emptyIfNull(suffix));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3990,7 +3990,7 @@ public class CharSequenceUtil extends StrChecker {
|
||||
public static String concat(final boolean isNullToEmpty, final CharSequence... strs) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
for (final CharSequence str : strs) {
|
||||
sb.append(isNullToEmpty ? nullToEmpty(str) : str);
|
||||
sb.append(isNullToEmpty ? emptyIfNull(str) : str);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package cn.hutool.core.thread;
|
||||
|
||||
import cn.hutool.core.util.RuntimeUtil;
|
||||
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletionService;
|
||||
@@ -129,7 +131,7 @@ public class ThreadUtil {
|
||||
}
|
||||
|
||||
// 最佳的线程数 = CPU可用核心数 / (1 - 阻塞系数)
|
||||
final int poolSize = (int) (Runtime.getRuntime().availableProcessors() / (1 - blockingCoefficient));
|
||||
final int poolSize = (int) (RuntimeUtil.getProcessorCount() / (1 - blockingCoefficient));
|
||||
return ExecutorBuilder.of().setCorePoolSize(poolSize).setMaxPoolSize(poolSize).setKeepAliveTime(0L).build();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package cn.hutool.core.util;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.iter.IterUtil;
|
||||
import cn.hutool.core.comparator.CompareUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
@@ -9,15 +10,13 @@ import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.math.NumberUtil;
|
||||
import cn.hutool.core.reflect.ClassUtil;
|
||||
import cn.hutool.core.reflect.MethodUtil;
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.core.text.StrUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Array;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@@ -29,13 +28,12 @@ import java.util.function.Supplier;
|
||||
public class ObjUtil {
|
||||
|
||||
/**
|
||||
* 比较两个对象是否相等。
|
||||
* 相同的条件有两个,满足其一即可:<br>
|
||||
* <ol>
|
||||
* <li>obj1 == null && obj2 == null</li>
|
||||
* <li>obj1.equals(obj2)</li>
|
||||
* <li>如果是BigDecimal比较,0 == obj1.compareTo(obj2)</li>
|
||||
* </ol>
|
||||
* <p>比较两个对象是否相等,满足下述任意条件即返回{@code true}:
|
||||
* <ul>
|
||||
* <li>若两对象皆为{@link BigDecimal},且满足{@code 0 == obj1.compareTo(obj2)}</li>
|
||||
* <li>{@code obj1 == null && obj2 == null}</li>
|
||||
* <li>{@code obj1.equals(obj2)}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param obj1 对象1
|
||||
* @param obj2 对象2
|
||||
@@ -50,27 +48,27 @@ public class ObjUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 比较两个对象是否不相等。<br>
|
||||
* 比较两个对象是否不相等
|
||||
*
|
||||
* @param obj1 对象1
|
||||
* @param obj2 对象2
|
||||
* @return 是否不等
|
||||
* @since 3.0.7
|
||||
* @see #equals(Object, Object)
|
||||
*/
|
||||
public static boolean notEquals(final Object obj1, final Object obj2) {
|
||||
return false == equals(obj1, obj2);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算对象长度,如果是字符串调用其length函数,集合类调用其size函数,数组调用其length属性,其他可遍历对象遍历计算长度<br>
|
||||
* 支持的类型包括:
|
||||
* <p>计算对象长度,支持类型包括:
|
||||
* <ul>
|
||||
* <li>CharSequence</li>
|
||||
* <li>Map</li>
|
||||
* <li>Iterator</li>
|
||||
* <li>Iterable</li>
|
||||
* <li>Enumeration</li>
|
||||
* <li>Array</li>
|
||||
* <li>{@code null}:默认返回{@code 0};</li>
|
||||
* <li>数组:返回数组长度;</li>
|
||||
* <li>{@link CharSequence}:返回{@link CharSequence#length()};</li>
|
||||
* <li>{@link Collection}:返回{@link Collection#size()};</li>
|
||||
* <li>{@link Iterator}或{@link Iterable}:可迭代的元素数量;</li>
|
||||
* <li>{@link Enumeration}:返回可迭代的元素数量;</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param obj 被计算长度的对象
|
||||
@@ -100,6 +98,9 @@ public class ObjUtil {
|
||||
}
|
||||
return count;
|
||||
}
|
||||
if (obj.getClass().isArray()) {
|
||||
return Array.getLength(obj);
|
||||
}
|
||||
if (obj instanceof Enumeration) {
|
||||
final Enumeration<?> enumeration = (Enumeration<?>) obj;
|
||||
count = 0;
|
||||
@@ -109,23 +110,21 @@ public class ObjUtil {
|
||||
}
|
||||
return count;
|
||||
}
|
||||
if (obj.getClass().isArray()) {
|
||||
return Array.getLength(obj);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对象中是否包含元素<br>
|
||||
* 支持的对象类型包括:
|
||||
* <p>检查{@code obj}中是否包含{@code element},若{@code obj}为{@code null},则直接返回{@code false}。<br>
|
||||
* 支持类型包括:
|
||||
* <ul>
|
||||
* <li>String</li>
|
||||
* <li>Collection</li>
|
||||
* <li>Map</li>
|
||||
* <li>Iterator</li>
|
||||
* <li>Iterable</li>
|
||||
* <li>Enumeration</li>
|
||||
* <li>Array</li>
|
||||
* <li>{@code null}:默认返回{@code false};</li>
|
||||
* <li>{@link String}:等同{@link String#contains(CharSequence)};</li>
|
||||
* <li>{@link Collection}:等同{@link Collection#contains(Object)};</li>
|
||||
* <li>{@link Map}:等同{@link Map#containsValue(Object)};</li>
|
||||
* <li>
|
||||
* {@link Iterator}、{@link Iterable}、{@link Enumeration}或数组:
|
||||
* 等同于遍历后对其元素调用{@link #equals(Object, Object)}方法;
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* @param obj 对象
|
||||
@@ -182,12 +181,7 @@ public class ObjUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查对象是否为null<br>
|
||||
* 判断标准为:
|
||||
*
|
||||
* <pre>
|
||||
* 1. == null
|
||||
* </pre>
|
||||
* 检查对象是否为{@code null}
|
||||
*
|
||||
* @param obj 对象
|
||||
* @return 是否为null
|
||||
@@ -197,7 +191,7 @@ public class ObjUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查对象是否不为null
|
||||
* 检查对象是否不为{@code null}
|
||||
*
|
||||
* @param obj 对象
|
||||
* @return 是否为null
|
||||
@@ -207,19 +201,26 @@ public class ObjUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断指定对象是否为空,支持:
|
||||
*
|
||||
* <pre>
|
||||
* 1. CharSequence
|
||||
* 2. Map
|
||||
* 3. Iterable
|
||||
* 4. Iterator
|
||||
* 5. Array
|
||||
* </pre>
|
||||
* 判断指定对象是否为空,支持类型包括:
|
||||
* <ul>
|
||||
* <li>{@code null}:默认返回{@code true};</li>
|
||||
* <li>数组:等同于{@link ArrayUtil#isEmpty(Object)};</li>
|
||||
* <li>{@link CharSequence}:等同于{@link CharSequenceUtil#isEmpty(CharSequence)};</li>
|
||||
* <li>{@link Collection}:等同于{@link CollUtil#isEmpty(Collection)};</li>
|
||||
* <li>{@link Map}:等同于{@link MapUtil#isEmpty(Map)};</li>
|
||||
* <li>
|
||||
* {@link Iterator}或{@link Iterable}:等同于{@link IterUtil#isEmpty(Iterator)}、
|
||||
* {@link IterUtil#isEmpty(Iterable)};
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* @param obj 被判断的对象
|
||||
* @return 是否为空,如果类型不支持,返回false
|
||||
* @since 4.5.7
|
||||
* @see StrUtil#isEmpty(CharSequence)
|
||||
* @see MapUtil#isEmpty(Map)
|
||||
* @see IterUtil#isEmpty(Iterable)
|
||||
* @see IterUtil#isEmpty(Iterator)
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static boolean isEmpty(final Object obj) {
|
||||
@@ -229,7 +230,9 @@ public class ObjUtil {
|
||||
|
||||
if (obj instanceof CharSequence) {
|
||||
return StrUtil.isEmpty((CharSequence) obj);
|
||||
} else if (obj instanceof Map) {
|
||||
} else if(obj instanceof Collection){
|
||||
return CollUtil.isEmpty((Collection)obj);
|
||||
}else if (obj instanceof Map) {
|
||||
return MapUtil.isEmpty((Map) obj);
|
||||
} else if (obj instanceof Iterable) {
|
||||
return IterUtil.isEmpty((Iterable) obj);
|
||||
@@ -243,34 +246,26 @@ public class ObjUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断指定对象是否为非空,支持:
|
||||
*
|
||||
* <pre>
|
||||
* 1. CharSequence
|
||||
* 2. Map
|
||||
* 3. Iterable
|
||||
* 4. Iterator
|
||||
* 5. Array
|
||||
* </pre>
|
||||
* 判断指定对象是否为非空
|
||||
*
|
||||
* @param obj 被判断的对象
|
||||
* @return 是否为空,如果类型不支持,返回true
|
||||
* @since 4.5.7
|
||||
* @see #isEmpty(Object)
|
||||
*/
|
||||
public static boolean isNotEmpty(final Object obj) {
|
||||
return false == isEmpty(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果给定对象为{@code null}返回默认值
|
||||
*
|
||||
* <pre>
|
||||
* ObjectUtil.defaultIfNull(null, null) = null
|
||||
* ObjectUtil.defaultIfNull(null, "") = ""
|
||||
* ObjectUtil.defaultIfNull(null, "zz") = "zz"
|
||||
* ObjectUtil.defaultIfNull("abc", *) = "abc"
|
||||
* ObjectUtil.defaultIfNull(Boolean.TRUE, *) = Boolean.TRUE
|
||||
* </pre>
|
||||
* <p>如果给定对象为{@code null}返回默认值
|
||||
* <pre>{@code
|
||||
* ObjectUtil.defaultIfNull(null, null); // = null
|
||||
* ObjectUtil.defaultIfNull(null, ""); // = ""
|
||||
* ObjectUtil.defaultIfNull(null, "zz"); // = "zz"
|
||||
* ObjectUtil.defaultIfNull("abc", *); // = "abc"
|
||||
* ObjectUtil.defaultIfNull(Boolean.TRUE, *); // = Boolean.TRUE
|
||||
* }</pre>
|
||||
*
|
||||
* @param <T> 对象类型
|
||||
* @param object 被检查对象,可能为{@code null}
|
||||
@@ -333,14 +328,20 @@ public class ObjUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 克隆对象<br>
|
||||
* 如果对象实现Cloneable接口,调用其clone方法<br>
|
||||
* 如果实现Serializable接口,执行深度克隆<br>
|
||||
* 否则返回{@code null}
|
||||
* <p>克隆对象
|
||||
* <ol>
|
||||
* <li>如果对象是数组,则等同于{@link ArrayUtil#clone(Object)};</li>
|
||||
* <li>如果对象实现了{@link Cloneable}接口,调用其{@code Cloneable#clone()}方法;</li>
|
||||
* <li>如果对象实现了{@link Serializable}接口,执行深度克隆;</li>
|
||||
* <li>不符合上述任意情况则返回{@code null};</li>
|
||||
* </ol>
|
||||
*
|
||||
* @param <T> 对象类型
|
||||
* @param obj 被克隆对象
|
||||
* @return 克隆后的对象
|
||||
* @see ArrayUtil#clone(Object)
|
||||
* @see Object#clone()
|
||||
* @see #cloneByStream(Object)
|
||||
*/
|
||||
public static <T> T clone(final T obj) {
|
||||
T result = ArrayUtil.clone(obj);
|
||||
@@ -360,6 +361,7 @@ public class ObjUtil {
|
||||
* @param <T> 对象类型
|
||||
* @param obj 对象
|
||||
* @return 克隆后或原对象
|
||||
* @see #clone(Object)
|
||||
*/
|
||||
public static <T> T cloneIfPossible(final T obj) {
|
||||
T clone = null;
|
||||
@@ -373,12 +375,13 @@ public class ObjUtil {
|
||||
|
||||
/**
|
||||
* 序列化后拷贝流的方式克隆<br>
|
||||
* 对象必须实现Serializable接口
|
||||
* 若对象未实现{@link Serializable}接口则默认返回{@code null}
|
||||
*
|
||||
* @param <T> 对象类型
|
||||
* @param obj 被克隆对象
|
||||
* @return 克隆后的对象
|
||||
* @throws UtilException IO异常和ClassNotFoundException封装
|
||||
* @see SerializeUtil#clone(Object)
|
||||
*/
|
||||
public static <T> T cloneByStream(final T obj) {
|
||||
return SerializeUtil.clone(obj);
|
||||
@@ -399,12 +402,15 @@ public class ObjUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否为有效的数字<br>
|
||||
* 检查Double和Float是否为无限大,或者Not a Number<br>
|
||||
* 非数字类型和Null将返回true
|
||||
* 检查是否为有效的数字,若对象不为{@link Number},则直接返回{@code true},否则:
|
||||
* <ul>
|
||||
* <li>若对象类型为{@link Double},则检查{@link Double#isInfinite()}或{@link Double#isNaN()};</li>
|
||||
* <li>若对象类型为{@link Float},则检查{@link Float#isInfinite()}或{@link Float#isNaN()};</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param obj 被检查类型
|
||||
* @return 检查结果,非数字类型和Null将返回true
|
||||
* @see NumberUtil#isValidNumber(Number)
|
||||
*/
|
||||
public static boolean isValidIfNumber(final Object obj) {
|
||||
if (obj instanceof Number) {
|
||||
@@ -454,7 +460,7 @@ public class ObjUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得给定类的第一个泛型参数
|
||||
* 获得给定类指定下标的泛型参数
|
||||
*
|
||||
* @param obj 被检查的对象
|
||||
* @param index 泛型类型的索引号,即第几个泛型类型
|
||||
@@ -466,16 +472,17 @@ public class ObjUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 将Object转为String<br>
|
||||
* 策略为:
|
||||
* <pre>
|
||||
* 1、null转为"null"
|
||||
* 2、调用Convert.toStr(Object)转换
|
||||
* </pre>
|
||||
* <p>将对象转为字符串
|
||||
* <ul>
|
||||
* <li>若对象为{@code null},则返回“null”;</li>
|
||||
* <li>若对象为{@link Map},则返回{@code Map#toString()};</li>
|
||||
* <li>若对象为其他类型,则调用{@link Convert#toStr(Object)}进行转换;</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param obj Bean对象
|
||||
* @return Bean所有字段转为Map后的字符串
|
||||
* @return 转换后的字符串
|
||||
* @since 3.2.0
|
||||
* @see Convert#toStr(Object)
|
||||
*/
|
||||
public static String toString(final Object obj) {
|
||||
if (null == obj) {
|
||||
@@ -484,7 +491,6 @@ public class ObjUtil {
|
||||
if (obj instanceof Map) {
|
||||
return obj.toString();
|
||||
}
|
||||
|
||||
return Convert.toStr(obj);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
/**
|
||||
* 系统运行时工具类,用于执行系统命令的工具
|
||||
@@ -234,11 +235,21 @@ public class RuntimeUtil {
|
||||
/**
|
||||
* 获得JVM可用的处理器数量(一般为CPU核心数)
|
||||
*
|
||||
* <p>
|
||||
* 这里做一个特殊的处理,在特殊的CPU上面,会有获取不到CPU数量的情况,所以这里做一个保护;
|
||||
* 默认给一个7,真实的CPU基本都是偶数,方便区分。
|
||||
* 如果不做处理,会出现创建线程池时{@link ThreadPoolExecutor},抛出异常:{@link IllegalArgumentException}
|
||||
*</p>
|
||||
*
|
||||
* @return 可用的处理器数量
|
||||
* @since 5.3.0
|
||||
*/
|
||||
public static int getProcessorCount() {
|
||||
return Runtime.getRuntime().availableProcessors();
|
||||
int cpu = Runtime.getRuntime().availableProcessors();
|
||||
if (cpu <= 0) {
|
||||
cpu = 7;
|
||||
}
|
||||
return cpu;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package cn.hutool.core.collection.iter;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* test for {@link ArrayIter}
|
||||
*/
|
||||
public class ArrayIterTest {
|
||||
|
||||
@Test
|
||||
public void testHasNext() {
|
||||
Integer[] arr = new Integer[]{ 1, 2, 3 };
|
||||
ArrayIter<Integer> iter = new ArrayIter<>(arr);
|
||||
Assert.assertTrue(iter.hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNext() {
|
||||
Integer[] arr = new Integer[]{ 1, 2, 3 };
|
||||
ArrayIter<Integer> iter = new ArrayIter<>(arr);
|
||||
Assert.assertEquals((Integer)1, iter.next());
|
||||
Assert.assertEquals((Integer)2, iter.next());
|
||||
Assert.assertEquals((Integer)3, iter.next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemove() {
|
||||
Integer[] arr = new Integer[]{ 1, 2, 3 };
|
||||
ArrayIter<Integer> iter = new ArrayIter<>(arr);
|
||||
Assert.assertThrows(UnsupportedOperationException.class, iter::remove);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetArray() {
|
||||
Integer[] arr = new Integer[]{ 1, 2, 3 };
|
||||
ArrayIter<Integer> iter = new ArrayIter<>(arr);
|
||||
Assert.assertEquals(arr, iter.getArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReset() {
|
||||
Integer[] arr = new Integer[]{ 1, 2, 3 };
|
||||
ArrayIter<Integer> iter = new ArrayIter<>(arr);
|
||||
Assert.assertEquals((Integer)1, iter.next());
|
||||
iter.reset();
|
||||
Assert.assertEquals((Integer)1, iter.next());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package cn.hutool.core.collection.iter;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* test for {@link CopiedIter}
|
||||
*/
|
||||
public class CopiedIterTest {
|
||||
|
||||
@Test
|
||||
public void copyOf() {
|
||||
List<Integer> list = Arrays.asList(1, 2, 3);
|
||||
Iterator<Integer> iter = list.iterator();
|
||||
Assert.assertEquals((Integer)1, iter.next());
|
||||
|
||||
Assert.assertEquals((Integer)2, CopiedIter.copyOf(iter).next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasNext() {
|
||||
Assert.assertTrue(CopiedIter.copyOf(Arrays.asList(1, 2, 3).iterator()).hasNext());
|
||||
Assert.assertFalse(CopiedIter.copyOf(Collections.emptyIterator()).hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void next() {
|
||||
List<Integer> list = Arrays.asList(1, 2, 3);
|
||||
Iterator<Integer> iter = CopiedIter.copyOf(list.iterator());
|
||||
Assert.assertEquals((Integer)1, iter.next());
|
||||
Assert.assertEquals((Integer)2, iter.next());
|
||||
Assert.assertEquals((Integer)3, iter.next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void remove() {
|
||||
List<Integer> list = Arrays.asList(1, 2, 3);
|
||||
Iterator<Integer> iter = CopiedIter.copyOf(list.iterator());
|
||||
Assert.assertThrows(UnsupportedOperationException.class, iter::remove);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package cn.hutool.core.collection.iter;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
* @author huangchengxing
|
||||
*/
|
||||
public class EnumerationIterTest {
|
||||
|
||||
@Test
|
||||
public void testHasNext() {
|
||||
Enumeration<Integer> enumeration = new IteratorEnumeration<>(Arrays.asList(1, 2, 3).iterator());
|
||||
EnumerationIter<Integer> iter = new EnumerationIter<>(enumeration);
|
||||
Assert.assertTrue(iter.hasNext());
|
||||
Assert.assertFalse(new EnumerationIter<>(new IteratorEnumeration<>(Collections.emptyIterator())).hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNext() {
|
||||
Enumeration<Integer> enumeration = new IteratorEnumeration<>(Arrays.asList(1, 2, 3).iterator());
|
||||
EnumerationIter<Integer> iter = new EnumerationIter<>(enumeration);
|
||||
Assert.assertEquals((Integer)1, iter.next());
|
||||
Assert.assertEquals((Integer)2, iter.next());
|
||||
Assert.assertEquals((Integer)3, iter.next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemove() {
|
||||
Enumeration<Integer> enumeration = new IteratorEnumeration<>(Arrays.asList(1, 2, 3).iterator());
|
||||
EnumerationIter<Integer> iter = new EnumerationIter<>(enumeration);
|
||||
Assert.assertThrows(UnsupportedOperationException.class, iter::remove);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIterator() {
|
||||
Enumeration<Integer> enumeration = new IteratorEnumeration<>(Arrays.asList(1, 2, 3).iterator());
|
||||
EnumerationIter<Integer> iter = new EnumerationIter<>(enumeration);
|
||||
Assert.assertSame(iter, iter.iterator());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,7 +4,10 @@ import cn.hutool.core.collection.ListUtil;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class FilterIterTest {
|
||||
|
||||
@@ -20,4 +23,40 @@ public class FilterIterTest {
|
||||
}
|
||||
Assert.assertEquals(2, count);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasNext() {
|
||||
Iterator<Integer> iter = new FilterIter<>(Arrays.asList(1, 2, 3).iterator(), i -> true);
|
||||
Assert.assertTrue(iter.hasNext());
|
||||
iter = new FilterIter<>(Collections.emptyIterator(), i -> true);
|
||||
Assert.assertFalse(iter.hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void next() {
|
||||
// 只保留奇数
|
||||
Iterator<Integer> iter = new FilterIter<>(Arrays.asList(1, 2, 3).iterator(), i -> (i & 1) == 1);
|
||||
Assert.assertEquals((Integer)1, iter.next());
|
||||
Assert.assertEquals((Integer)3, iter.next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void remove() {
|
||||
Iterator<Integer> iter = new FilterIter<>(Collections.emptyIterator(), i -> true);
|
||||
Assert.assertThrows(IllegalStateException.class, iter::remove);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getIterator() {
|
||||
FilterIter<Integer> iter = new FilterIter<>(Collections.emptyIterator(), i -> true);
|
||||
Assert.assertSame(Collections.emptyIterator(), iter.getIterator());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getFilter() {
|
||||
Predicate<Integer> predicate = i -> true;
|
||||
FilterIter<Integer> iter = new FilterIter<>(Collections.emptyIterator(), predicate);
|
||||
Assert.assertSame(predicate, iter.getFilter());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package cn.hutool.core.collection.iter;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* test for {@link IterChain}
|
||||
*/
|
||||
public class IterChainTest {
|
||||
|
||||
@Test
|
||||
public void testAddChain() {
|
||||
Iterator<Integer> iter1 = Arrays.asList(1, 2).iterator();
|
||||
Iterator<Integer> iter2 = Arrays.asList(3, 4).iterator();
|
||||
IterChain<Integer> iterChain = new IterChain<>();
|
||||
Assert.assertSame(iterChain, iterChain.addChain(iter1));
|
||||
Assert.assertSame(iterChain, iterChain.addChain(iter2));
|
||||
Assert.assertEquals(2, iterChain.allIterators.size());
|
||||
|
||||
iterChain = new IterChain<>(iter1, iter2);
|
||||
Assert.assertEquals(2, iterChain.allIterators.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasNext() {
|
||||
IterChain<Integer> iterChain = new IterChain<>();
|
||||
Assert.assertFalse(iterChain.hasNext());
|
||||
Assert.assertFalse(iterChain.addChain(Collections.emptyIterator()).hasNext());
|
||||
Assert.assertTrue(iterChain.addChain(Arrays.asList(3, 4).iterator()).hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNext() {
|
||||
Iterator<Integer> iter1 = Arrays.asList(1, 2).iterator();
|
||||
Iterator<Integer> iter2 = Arrays.asList(3, 4).iterator();
|
||||
IterChain<Integer> iterChain = new IterChain<>();
|
||||
Assert.assertSame(iterChain, iterChain.addChain(iter1));
|
||||
Assert.assertSame(iterChain, iterChain.addChain(iter2));
|
||||
Assert.assertEquals((Integer)1, iterChain.next());
|
||||
Assert.assertEquals((Integer)2, iterChain.next());
|
||||
Assert.assertEquals((Integer)3, iterChain.next());
|
||||
Assert.assertEquals((Integer)4, iterChain.next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemove() {
|
||||
IterChain<Integer> iterChain = new IterChain<>();
|
||||
iterChain.addChain(Arrays.asList(1, 2).iterator());
|
||||
Assert.assertThrows(IllegalStateException.class, iterChain::remove);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIterator() {
|
||||
Iterator<Integer> iter1 = Arrays.asList(1, 2).iterator();
|
||||
Iterator<Integer> iter2 = Arrays.asList(3, 4).iterator();
|
||||
IterChain<Integer> iterChain = new IterChain<>();
|
||||
Assert.assertSame(iterChain, iterChain.addChain(iter1));
|
||||
Assert.assertSame(iterChain, iterChain.addChain(iter2));
|
||||
|
||||
Iterator<Iterator<Integer>> iterators = iterChain.iterator();
|
||||
Assert.assertSame(iter1, iterators.next());
|
||||
Assert.assertSame(iter2, iterators.next());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,306 @@
|
||||
package cn.hutool.core.collection.iter;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* test for {@link IterUtil}
|
||||
*/
|
||||
public class IterUtilTest {
|
||||
|
||||
@Test
|
||||
public void testGetIter() {
|
||||
Assert.assertNull(IterUtil.getIter(null));
|
||||
Assert.assertEquals(Collections.emptyIterator(), IterUtil.getIter(Collections.emptyList()));
|
||||
|
||||
Assert.assertNull(IterUtil.getIter((Object)null));
|
||||
Assert.assertNotNull(IterUtil.getIter(Collections.emptyIterator()));
|
||||
Assert.assertNotNull(IterUtil.getIter((Object)Collections.emptyList()));
|
||||
Assert.assertNotNull(IterUtil.getIter(new Integer[0]));
|
||||
Assert.assertNotNull(IterUtil.getIter(Collections.emptyMap()));
|
||||
Assert.assertNull(IterUtil.getIter((NodeList)null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsEmpty() {
|
||||
Assert.assertTrue(IterUtil.isEmpty(Collections.emptyIterator()));
|
||||
Assert.assertFalse(IterUtil.isEmpty(Arrays.asList(1, 2).iterator()));
|
||||
|
||||
Assert.assertTrue(IterUtil.isEmpty(Collections.emptyList()));
|
||||
Assert.assertFalse(IterUtil.isEmpty(Arrays.asList(1, 2)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsNotEmpty() {
|
||||
Assert.assertFalse(IterUtil.isNotEmpty(Collections.emptyIterator()));
|
||||
Assert.assertTrue(IterUtil.isNotEmpty(Arrays.asList(1, 2).iterator()));
|
||||
|
||||
Assert.assertFalse(IterUtil.isNotEmpty(Collections.emptyList()));
|
||||
Assert.assertTrue(IterUtil.isNotEmpty(Arrays.asList(1, 2)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasNull() {
|
||||
Assert.assertFalse(IterUtil.hasNull(Arrays.asList(1, 3, 2).iterator()));
|
||||
Assert.assertTrue(IterUtil.hasNull(Arrays.asList(1, null, 2).iterator()));
|
||||
Assert.assertFalse(IterUtil.hasNull(Collections.emptyIterator()));
|
||||
Assert.assertTrue(IterUtil.hasNull(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAllNull() {
|
||||
Assert.assertTrue(IterUtil.isAllNull(Arrays.asList(null, null)));
|
||||
Assert.assertFalse(IterUtil.isAllNull(Arrays.asList(1, null)));
|
||||
Assert.assertTrue(IterUtil.isAllNull((Iterable<?>)null));
|
||||
Assert.assertTrue(IterUtil.isAllNull(Arrays.asList(null, null).iterator()));
|
||||
Assert.assertFalse(IterUtil.isAllNull(Arrays.asList(1, null).iterator()));
|
||||
Assert.assertTrue(IterUtil.isAllNull((Iterator<?>)null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCountMap() {
|
||||
Object o1 = new Object();
|
||||
Object o2 = new Object();
|
||||
Map<Object, Integer> countMap = IterUtil.countMap(Arrays.asList(o1, o2, o1, o1).iterator());
|
||||
Assert.assertEquals((Integer)3, countMap.get(o1));
|
||||
Assert.assertEquals((Integer)1, countMap.get(o2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFieldValueMap() {
|
||||
Bean bean1 = new Bean(1, "A");
|
||||
Bean bean2 = new Bean(2, "B");
|
||||
Map<Integer, Bean> map = IterUtil.fieldValueMap(Arrays.asList(bean1, bean2).iterator(), "id");
|
||||
Assert.assertEquals(bean1, map.get(1));
|
||||
Assert.assertEquals(bean2, map.get(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFieldValueAsMap() {
|
||||
Bean bean1 = new Bean(1, "A");
|
||||
Bean bean2 = new Bean(2, "B");
|
||||
Map<Integer, String> map = IterUtil.fieldValueAsMap(
|
||||
Arrays.asList(bean1, bean2).iterator(), "id", "name"
|
||||
);
|
||||
Assert.assertEquals("A", map.get(1));
|
||||
Assert.assertEquals("B", map.get(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFieldValueList() {
|
||||
Bean bean1 = new Bean(1, "A");
|
||||
Bean bean2 = new Bean(2, "B");
|
||||
Assert.assertEquals(Arrays.asList(1, 2), IterUtil.fieldValueList(Arrays.asList(bean1, bean2), "id"));
|
||||
Assert.assertEquals(
|
||||
Arrays.asList(1, 2),
|
||||
IterUtil.fieldValueList(Arrays.asList(bean1, bean2).iterator(), "id")
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJoin() {
|
||||
List<String> stringList = Arrays.asList("1", "2", "3");
|
||||
Assert.assertEquals("123", IterUtil.join(stringList.iterator(), ""));
|
||||
Assert.assertEquals("-1--2--3-", IterUtil.join(stringList.iterator(), "", "-", "-"));
|
||||
Assert.assertEquals("123", IterUtil.join(stringList.iterator(), "", Function.identity()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToMap() {
|
||||
List<Integer> keys = Arrays.asList(1, 2, 3);
|
||||
|
||||
Map<Integer, Integer> map = IterUtil.toMap(keys, keys);
|
||||
Assert.assertEquals(keys, new ArrayList<>(map.keySet()));
|
||||
Assert.assertEquals(keys, new ArrayList<>(map.values()));
|
||||
|
||||
map = IterUtil.toMap(keys.iterator(), keys.iterator());
|
||||
Assert.assertEquals(keys, new ArrayList<>(map.keySet()));
|
||||
Assert.assertEquals(keys, new ArrayList<>(map.values()));
|
||||
|
||||
map = IterUtil.toMap(keys.iterator(), keys.iterator(), true);
|
||||
Assert.assertEquals(keys, new ArrayList<>(map.keySet()));
|
||||
Assert.assertEquals(keys, new ArrayList<>(map.values()));
|
||||
|
||||
map = IterUtil.toMap(keys, keys, true);
|
||||
Assert.assertEquals(keys, new ArrayList<>(map.keySet()));
|
||||
Assert.assertEquals(keys, new ArrayList<>(map.values()));
|
||||
|
||||
map = IterUtil.toMap(keys, Function.identity());
|
||||
Assert.assertEquals(keys, new ArrayList<>(map.keySet()));
|
||||
Assert.assertEquals(keys, new ArrayList<>(map.values()));
|
||||
|
||||
map = IterUtil.toMap(keys, Function.identity(), Function.identity());
|
||||
Assert.assertEquals(keys, new ArrayList<>(map.keySet()));
|
||||
Assert.assertEquals(keys, new ArrayList<>(map.values()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToListMap() {
|
||||
List<Integer> keys = Arrays.asList(1, 2, 3, 4);
|
||||
|
||||
Map<Boolean, List<Integer>> map = IterUtil.toListMap(keys, i -> (i & 1) == 0, Function.identity());
|
||||
Assert.assertEquals(Arrays.asList(2, 4), map.get(true));
|
||||
Assert.assertEquals(Arrays.asList(1, 3), map.get(false));
|
||||
|
||||
map = IterUtil.toListMap(keys, i -> (i & 1) == 0);
|
||||
Assert.assertEquals(Arrays.asList(2, 4), map.get(true));
|
||||
Assert.assertEquals(Arrays.asList(1, 3), map.get(false));
|
||||
|
||||
map = new LinkedHashMap<>();
|
||||
Map<Boolean, List<Integer>> rawMap = IterUtil.toListMap(map, keys, i -> (i & 1) == 0, Function.identity());
|
||||
Assert.assertSame(rawMap, map);
|
||||
Assert.assertEquals(Arrays.asList(2, 4), rawMap.get(true));
|
||||
Assert.assertEquals(Arrays.asList(1, 3), rawMap.get(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAsIterable() {
|
||||
Iterator<Integer> iter = Arrays.asList(1, 2, 3).iterator();
|
||||
Assert.assertEquals(iter, IterUtil.asIterable(iter).iterator());
|
||||
Assert.assertNull(IterUtil.asIterable(null).iterator());
|
||||
|
||||
Enumeration<Integer> enumeration = new IteratorEnumeration<>(iter);
|
||||
Iterator<Integer> iter2 = IterUtil.asIterator(enumeration);
|
||||
Assert.assertEquals((Integer)1, iter2.next());
|
||||
Assert.assertEquals((Integer)2, iter2.next());
|
||||
Assert.assertEquals((Integer)3, iter2.next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGet() {
|
||||
Iterator<Integer> iter = Arrays.asList(1, 2, 3, 4).iterator();
|
||||
Assert.assertEquals((Integer)3, IterUtil.get(iter, 2));
|
||||
Assert.assertThrows(IllegalArgumentException.class, () -> IterUtil.get(iter, -1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetFirst() {
|
||||
Iterator<Integer> iter = Arrays.asList(1, 2, 3, 4).iterator();
|
||||
Assert.assertEquals((Integer)1, IterUtil.getFirst(iter));
|
||||
Assert.assertNull(IterUtil.getFirst(null));
|
||||
Assert.assertNull(IterUtil.getFirst(Collections.emptyIterator()));
|
||||
|
||||
Assert.assertEquals((Integer)2, IterUtil.getFirst(iter, t -> (t & 1) == 0));
|
||||
Assert.assertNull(IterUtil.getFirst((Iterator<Integer>)null, t -> (t & 1) == 0));
|
||||
Assert.assertNull(IterUtil.getFirst(Collections.emptyIterator(), Objects::nonNull));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetFirstNoneNull() {
|
||||
Iterator<Integer> iter = Arrays.asList(null, 2, null, 4).iterator();
|
||||
Assert.assertEquals((Integer)2, IterUtil.getFirstNoneNull(iter));
|
||||
Assert.assertNull(IterUtil.getFirstNoneNull(null));
|
||||
Assert.assertNull(IterUtil.getFirstNoneNull(Collections.emptyIterator()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetElementType() {
|
||||
List<Object> list = Arrays.asList(null, "str", null);
|
||||
Assert.assertEquals(String.class, IterUtil.getElementType(list));
|
||||
Assert.assertNull(IterUtil.getElementType((Iterable<?>)null));
|
||||
Assert.assertNull(IterUtil.getElementType(Collections.emptyList()));
|
||||
|
||||
Assert.assertEquals(String.class, IterUtil.getElementType(list.iterator()));
|
||||
Assert.assertNull(IterUtil.getElementType((Iterator<?>)null));
|
||||
Assert.assertNull(IterUtil.getElementType(Collections.emptyIterator()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEdit() {
|
||||
Assert.assertEquals(
|
||||
Collections.singletonList("str"),
|
||||
IterUtil.edit(Arrays.asList(null, "str", null).iterator(), t -> t)
|
||||
);
|
||||
Assert.assertEquals(
|
||||
Collections.singletonList("str"),
|
||||
IterUtil.edit(Arrays.asList(null, "str", null).iterator(), null)
|
||||
);
|
||||
Assert.assertEquals(Collections.emptyList(), IterUtil.edit(null, t -> t));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemove() {
|
||||
List<Integer> list = new ArrayList<>(Arrays.asList(1, null, null, 3));
|
||||
IterUtil.remove(list.iterator(), Objects::isNull);
|
||||
Assert.assertEquals(Arrays.asList(1, 3), list);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFilterToList() {
|
||||
List<Integer> list1 = new ArrayList<>(Arrays.asList(1, null, null, 3));
|
||||
List<Integer> list2 = IterUtil.filterToList(list1.iterator(), Objects::nonNull);
|
||||
Assert.assertSame(list1, list1);
|
||||
Assert.assertEquals(Arrays.asList(1, 3), list2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFiltered() {
|
||||
Assert.assertNotNull(IterUtil.filtered(Collections.emptyIterator(), t -> true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmpty() {
|
||||
Assert.assertSame(Collections.emptyIterator(), IterUtil.empty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTrans() {
|
||||
Assert.assertNotNull(IterUtil.trans(Collections.emptyIterator(), t -> true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSize() {
|
||||
Assert.assertEquals(0, IterUtil.size((Iterator<?>)null));
|
||||
Assert.assertEquals(0, IterUtil.size(Collections.emptyIterator()));
|
||||
Assert.assertEquals(3, IterUtil.size(Arrays.asList(1, 2, 3).iterator()));
|
||||
|
||||
Assert.assertEquals(0, IterUtil.size((Iterable<?>)null));
|
||||
Assert.assertEquals(0, IterUtil.size(Collections.emptyList()));
|
||||
Assert.assertEquals(3, IterUtil.size(Arrays.asList(1, 2, 3)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsEqualList() {
|
||||
Assert.assertFalse(IterUtil.isEqualList(null, Collections.emptyList()));
|
||||
Assert.assertFalse(IterUtil.isEqualList(Arrays.asList(1, 2, 3), Collections.emptyList()));
|
||||
Assert.assertFalse(IterUtil.isEqualList(Arrays.asList(1, 2, 3), Arrays.asList(1, 2)));
|
||||
Assert.assertTrue(IterUtil.isEqualList(Arrays.asList(1, 2, 3), Arrays.asList(1, 2, 3)));
|
||||
Assert.assertTrue(IterUtil.isEqualList(null, null));
|
||||
Assert.assertTrue(IterUtil.isEqualList(Collections.emptyList(), Collections.emptyList()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClear() {
|
||||
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3));
|
||||
IterUtil.clear(list.iterator());
|
||||
Assert.assertTrue(list.isEmpty());
|
||||
Assert.assertThrows(UnsupportedOperationException.class, () -> IterUtil.clear(Arrays.asList(1, 2).iterator()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToStr() {
|
||||
List<Integer> list = Arrays.asList(1, 2, 3);
|
||||
Assert.assertEquals("[1, 2, 3]", IterUtil.toStr(list.iterator()));
|
||||
Assert.assertEquals("[1, 2, 3]", IterUtil.toStr(list.iterator(), Objects::toString));
|
||||
Assert.assertEquals("{1:2:3}", IterUtil.toStr(list.iterator(), Objects::toString, ":", "{", "}"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForEach() {
|
||||
List<Integer> list = new ArrayList<>();
|
||||
IterUtil.forEach(Arrays.asList(1, 2, 3, 4).iterator(), list::add);
|
||||
Assert.assertEquals(Arrays.asList(1, 2, 3, 4), list);
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
private static class Bean {
|
||||
private final Integer id;
|
||||
private final String name;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package cn.hutool.core.collection.iter;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* test for {@link IteratorEnumeration}
|
||||
*/
|
||||
public class IteratorEnumerationTest {
|
||||
|
||||
@Test
|
||||
public void testHasMoreElements() {
|
||||
List<Integer> list = Arrays.asList(1, 2, 3);
|
||||
IteratorEnumeration<Integer> enumeration = new IteratorEnumeration<>(list.iterator());
|
||||
Assert.assertTrue(enumeration.hasMoreElements());
|
||||
Assert.assertFalse(new IteratorEnumeration<>(Collections.emptyIterator()).hasMoreElements());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNextElement() {
|
||||
List<Integer> list = Arrays.asList(1, 2, 3);
|
||||
IteratorEnumeration<Integer> enumeration = new IteratorEnumeration<>(list.iterator());
|
||||
Assert.assertEquals((Integer)1, enumeration.nextElement());
|
||||
Assert.assertEquals((Integer)2, enumeration.nextElement());
|
||||
Assert.assertEquals((Integer)3, enumeration.nextElement());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package cn.hutool.core.collection.iter;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* test for {@link LineIter}
|
||||
*/
|
||||
public class LineIterTest {
|
||||
|
||||
@Test
|
||||
public void testHasNext() {
|
||||
LineIter iter = getItrFromClasspathFile();
|
||||
Assert.assertTrue(iter.hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNext() {
|
||||
LineIter iter = getItrFromClasspathFile();
|
||||
Assert.assertEquals("is first line", iter.next());
|
||||
Assert.assertEquals("is second line", iter.next());
|
||||
Assert.assertEquals("is third line", iter.next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemove() {
|
||||
LineIter iter = getItrFromClasspathFile();
|
||||
iter.next();
|
||||
Assert.assertThrows(UnsupportedOperationException.class, iter::remove);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFinish() {
|
||||
LineIter iter = getItrFromClasspathFile();
|
||||
iter.finish();
|
||||
Assert.assertThrows(NoSuchElementException.class, iter::next);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClose() throws IOException {
|
||||
URL url = LineIterTest.class.getClassLoader().getResource("text.txt");
|
||||
Assert.assertNotNull(url);
|
||||
FileInputStream inputStream = new FileInputStream(url.getFile());
|
||||
LineIter iter = new LineIter(inputStream, StandardCharsets.UTF_8);
|
||||
iter.close();
|
||||
Assert.assertThrows(NoSuchElementException.class, iter::next);
|
||||
Assert.assertThrows(IOException.class, inputStream::read);
|
||||
}
|
||||
|
||||
private static LineIter getItrFromClasspathFile() {
|
||||
URL url = LineIterTest.class.getClassLoader().getResource("text.txt");
|
||||
Assert.assertNotNull(url);
|
||||
FileInputStream inputStream = null;
|
||||
try {
|
||||
inputStream = new FileInputStream(url.getFile());
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
return new LineIter(bufferedReader);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package cn.hutool.core.collection.iter;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* test for {@link PartitionIter}
|
||||
*/
|
||||
public class PartitionIterTest {
|
||||
|
||||
@Test
|
||||
public void testHasNext() {
|
||||
Iterator<Integer> iter = Arrays.asList(1, 2, 3, 4).iterator();
|
||||
PartitionIter<Integer> partitionIter = new PartitionIter<>(iter, 2);
|
||||
Assert.assertTrue(partitionIter.hasNext());
|
||||
Assert.assertFalse(new PartitionIter<>(Collections.emptyIterator(), 1).hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNext() {
|
||||
Iterator<Integer> iter = Arrays.asList(1, 2, 3, 4).iterator();
|
||||
PartitionIter<Integer> partitionIter = new PartitionIter<>(iter, 2);
|
||||
Assert.assertEquals(Arrays.asList(1, 2), partitionIter.next());
|
||||
Assert.assertEquals(Arrays.asList(3, 4), partitionIter.next());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package cn.hutool.core.collection.iter;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* @author huangchengxing
|
||||
*/
|
||||
public class TransIterTest {
|
||||
|
||||
@Test
|
||||
public void testHasNext() {
|
||||
TransIter<Integer, String> iter = new TransIter<>(Arrays.asList(1, 2, 3).iterator(), String::valueOf);
|
||||
Assert.assertTrue(iter.hasNext());
|
||||
Assert.assertFalse(new TransIter<>(Collections.emptyIterator(), Function.identity()).hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNext() {
|
||||
TransIter<Integer, String> iter = new TransIter<>(Arrays.asList(1, 2, 3).iterator(), String::valueOf);
|
||||
Assert.assertEquals("1", iter.next());
|
||||
Assert.assertEquals("2", iter.next());
|
||||
Assert.assertEquals("3", iter.next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemove() {
|
||||
List<Integer> list = ListUtil.of(1, 2, 3);
|
||||
TransIter<Integer, String> iter = new TransIter<>(list.iterator(), String::valueOf);
|
||||
iter.next();
|
||||
iter.remove();
|
||||
iter.next();
|
||||
iter.remove();
|
||||
iter.next();
|
||||
iter.remove();
|
||||
Assert.assertTrue(list.isEmpty());
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,6 @@ import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.util.Objects;
|
||||
|
||||
public class TimeUtilTest {
|
||||
@@ -234,7 +233,49 @@ public class TimeUtilTest {
|
||||
@Test
|
||||
public void ofTest2(){
|
||||
final Instant instant = Objects.requireNonNull(DateUtil.parse("2022-02-22")).toInstant();
|
||||
final LocalDateTime of = TimeUtil.of((TemporalAccessor) instant);
|
||||
final LocalDateTime of = TimeUtil.of(instant);
|
||||
Console.log(of);
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Test
|
||||
public void isInTest() {
|
||||
// 时间范围 8点-9点
|
||||
final LocalDateTime begin = LocalDateTime.parse("2019-02-02T08:00:00");
|
||||
final LocalDateTime end = LocalDateTime.parse("2019-02-02T09:00:00");
|
||||
|
||||
// 不在时间范围内 用例
|
||||
Assert.assertFalse(TimeUtil.isIn(LocalDateTime.parse("2019-02-02T06:00:00"), begin, end));
|
||||
Assert.assertFalse(TimeUtil.isIn(LocalDateTime.parse("2019-02-02T13:00:00"), begin, end));
|
||||
Assert.assertFalse(TimeUtil.isIn(LocalDateTime.parse("2019-02-01T08:00:00"), begin, end));
|
||||
Assert.assertFalse(TimeUtil.isIn(LocalDateTime.parse("2019-02-03T09:00:00"), begin, end));
|
||||
|
||||
// 在时间范围内 用例
|
||||
Assert.assertTrue(TimeUtil.isIn(LocalDateTime.parse("2019-02-02T08:00:00"), begin, end));
|
||||
Assert.assertTrue(TimeUtil.isIn(LocalDateTime.parse("2019-02-02T08:00:01"), begin, end));
|
||||
Assert.assertTrue(TimeUtil.isIn(LocalDateTime.parse("2019-02-02T08:11:00"), begin, end));
|
||||
Assert.assertTrue(TimeUtil.isIn(LocalDateTime.parse("2019-02-02T08:22:00"), begin, end));
|
||||
Assert.assertTrue(TimeUtil.isIn(LocalDateTime.parse("2019-02-02T08:59:59"), begin, end));
|
||||
Assert.assertTrue(TimeUtil.isIn(LocalDateTime.parse("2019-02-02T09:00:00"), begin, end));
|
||||
|
||||
// 测试边界条件
|
||||
Assert.assertTrue(TimeUtil.isIn(begin, begin, end, true, false));
|
||||
Assert.assertFalse(TimeUtil.isIn(begin, begin, end, false, false));
|
||||
Assert.assertTrue(TimeUtil.isIn(end, begin, end, false, true));
|
||||
Assert.assertFalse(TimeUtil.isIn(end, begin, end, false, false));
|
||||
|
||||
// begin、end互换
|
||||
Assert.assertTrue(TimeUtil.isIn(begin, end, begin, true, true));
|
||||
|
||||
// 比较当前时间范围
|
||||
final LocalDateTime now = LocalDateTime.now();
|
||||
Assert.assertTrue(TimeUtil.isIn(now, now.minusHours(1L), now.plusHours(1L)));
|
||||
Assert.assertFalse(TimeUtil.isIn(now, now.minusHours(1L), now.minusHours(2L)));
|
||||
Assert.assertFalse(TimeUtil.isIn(now, now.plusHours(1L), now.plusHours(2L)));
|
||||
|
||||
// 异常入参
|
||||
Assert.assertThrows(IllegalArgumentException.class, () -> TimeUtil.isIn(null, begin, end, false, false));
|
||||
Assert.assertThrows(IllegalArgumentException.class, () -> TimeUtil.isIn(begin, null, end, false, false));
|
||||
Assert.assertThrows(IllegalArgumentException.class, () -> TimeUtil.isIn(begin, begin, null, false, false));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,14 +47,14 @@ public class CollectorUtilTest {
|
||||
|
||||
@Test
|
||||
public void testToEasyStream() {
|
||||
Stream<Integer> stream =Stream.of(1, 2, 3, 4)
|
||||
final Stream<Integer> stream =Stream.of(1, 2, 3, 4)
|
||||
.collect(CollectorUtil.toEasyStream());
|
||||
Assert.assertEquals(EasyStream.class, stream.getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToEntryStream() {
|
||||
Map<String, Integer> map = Stream.of(1, 2, 3, 4, 5)
|
||||
final Map<String, Integer> map = Stream.of(1, 2, 3, 4, 5)
|
||||
// 转为EntryStream
|
||||
.collect(CollectorUtil.toEntryStream(Function.identity(), String::valueOf))
|
||||
// 过滤偶数
|
||||
|
||||
@@ -218,7 +218,7 @@ public class EasyStreamTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPeek(){
|
||||
public void testPeek() {
|
||||
EasyStream.of("one", "two", "three", "four")
|
||||
.filter(e -> e.length() == 4)
|
||||
.peek(e -> Assert.assertEquals("four", e))
|
||||
@@ -228,12 +228,12 @@ public class EasyStreamTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPeekIdx(){
|
||||
public void testPeekIdx() {
|
||||
EasyStream.of("one", "two", "three", "four")
|
||||
.filter(e -> e.length() == 4)
|
||||
.peekIdx((e,i) -> Assert.assertEquals("four:0", e + ":" + i))
|
||||
.peekIdx((e, i) -> Assert.assertEquals("four:0", e + ":" + i))
|
||||
.map(String::toUpperCase)
|
||||
.peekIdx((e,i) -> Assert.assertEquals("FOUR:0", e + ":" + i))
|
||||
.peekIdx((e, i) -> Assert.assertEquals("FOUR:0", e + ":" + i))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@@ -431,7 +431,7 @@ public class EasyStreamTest {
|
||||
@Test
|
||||
public void testToTree() {
|
||||
Consumer<Object> test = o -> {
|
||||
List<Student> studentTree = EasyStream
|
||||
final List<Student> studentTree = EasyStream
|
||||
.of(
|
||||
Student.builder().id(1L).name("dromara").build(),
|
||||
Student.builder().id(2L).name("baomidou").build(),
|
||||
@@ -464,7 +464,7 @@ public class EasyStreamTest {
|
||||
), studentTree);
|
||||
};
|
||||
test = test.andThen(o -> {
|
||||
List<Student> studentTree = EasyStream
|
||||
final List<Student> studentTree = EasyStream
|
||||
.of(
|
||||
Student.builder().id(1L).name("dromara").matchParent(true).build(),
|
||||
Student.builder().id(2L).name("baomidou").matchParent(true).build(),
|
||||
@@ -501,7 +501,7 @@ public class EasyStreamTest {
|
||||
|
||||
@Test
|
||||
public void testFlatTree() {
|
||||
List<Student> studentTree = asList(
|
||||
final List<Student> studentTree = asList(
|
||||
Student.builder().id(1L).name("dromara")
|
||||
.children(asList(Student.builder().id(3L).name("hutool").parentId(1L)
|
||||
.children(singletonList(Student.builder().id(6L).name("looly").parentId(3L).build()))
|
||||
@@ -551,9 +551,9 @@ public class EasyStreamTest {
|
||||
@Test
|
||||
public void testTransform() {
|
||||
final boolean result = EasyStream.of(1, 2, 3)
|
||||
.transform(EasyStream::toList)
|
||||
.map(List::isEmpty)
|
||||
.orElse(false);
|
||||
.transform(EasyStream::toList)
|
||||
.map(List::isEmpty)
|
||||
.orElse(false);
|
||||
Assert.assertFalse(result);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,23 @@
|
||||
package cn.hutool.core.util;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.exceptions.CloneRuntimeException;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* test for {@link ObjUtil}
|
||||
*/
|
||||
public class ObjUtilTest {
|
||||
|
||||
@Test
|
||||
@@ -56,43 +62,49 @@ public class ObjUtilTest {
|
||||
|
||||
final Iterable<Integer> list = ListUtil.of(1, 2, 3);
|
||||
Assert.assertEquals(3, ObjUtil.length(list));
|
||||
Assert.assertEquals(3, ObjUtil.length(Arrays.asList(1, 2, 3).iterator()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void containsTest(){
|
||||
final int[] array = new int[]{1,2,3,4,5};
|
||||
|
||||
final boolean contains = ObjUtil.contains(array, 1);
|
||||
Assert.assertTrue(contains);
|
||||
Assert.assertTrue(ObjUtil.contains(new int[]{1,2,3,4,5}, 1));
|
||||
Assert.assertFalse(ObjUtil.contains(null, 1));
|
||||
Assert.assertTrue(ObjUtil.contains("123", "3"));
|
||||
Map<Integer, Integer> map = new HashMap<>();
|
||||
map.put(1, 1);
|
||||
map.put(2, 2);
|
||||
Assert.assertTrue(ObjUtil.contains(map, 1));
|
||||
Assert.assertTrue(ObjUtil.contains(Arrays.asList(1, 2, 3).iterator(), 2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cloneTest() {
|
||||
final Obj obj = new Obj();
|
||||
final Obj obj2 = ObjUtil.clone(obj);
|
||||
Assert.assertEquals("OK", obj2.doSomeThing());
|
||||
}
|
||||
|
||||
static class Obj implements Cloneable {
|
||||
public String doSomeThing() {
|
||||
return "OK";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Obj clone() {
|
||||
try {
|
||||
return (Obj) super.clone();
|
||||
} catch (final CloneNotSupportedException e) {
|
||||
throw new CloneRuntimeException(e);
|
||||
}
|
||||
}
|
||||
public void isNullTest() {
|
||||
Assert.assertTrue(ObjUtil.isNull(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toStringTest() {
|
||||
final ArrayList<String> strings = ListUtil.of("1", "2");
|
||||
final String result = ObjUtil.toString(strings);
|
||||
Assert.assertEquals("[1, 2]", result);
|
||||
public void isNotNullTest() {
|
||||
Assert.assertFalse(ObjUtil.isNotNull(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isEmptyTest() {
|
||||
Assert.assertTrue(ObjUtil.isEmpty(null));
|
||||
Assert.assertTrue(ObjUtil.isEmpty(new int[0]));
|
||||
Assert.assertTrue(ObjUtil.isEmpty(""));
|
||||
Assert.assertTrue(ObjUtil.isEmpty(Collections.emptyList()));
|
||||
Assert.assertTrue(ObjUtil.isEmpty(Collections.emptyMap()));
|
||||
Assert.assertTrue(ObjUtil.isEmpty(Collections.emptyIterator()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isNotEmptyTest() {
|
||||
Assert.assertFalse(ObjUtil.isNotEmpty(null));
|
||||
Assert.assertFalse(ObjUtil.isNotEmpty(new int[0]));
|
||||
Assert.assertFalse(ObjUtil.isNotEmpty(""));
|
||||
Assert.assertFalse(ObjUtil.isNotEmpty(Collections.emptyList()));
|
||||
Assert.assertFalse(ObjUtil.isNotEmpty(Collections.emptyMap()));
|
||||
Assert.assertFalse(ObjUtil.isNotEmpty(Collections.emptyIterator()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -113,6 +125,48 @@ public class ObjUtilTest {
|
||||
Assert.assertSame(val2, ObjUtil.defaultIfNull(null, Function.identity(), val2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cloneTest() {
|
||||
Assert.assertNull(ObjUtil.clone(null));
|
||||
|
||||
final CloneableBean cloneableBean1 = new CloneableBean(1);
|
||||
final CloneableBean cloneableBean2 = ObjUtil.clone(cloneableBean1);
|
||||
Assert.assertEquals(cloneableBean1, cloneableBean2);
|
||||
|
||||
final SerializableBean serializableBean1 = new SerializableBean(2);
|
||||
final SerializableBean serializableBean2 = ObjUtil.clone(serializableBean1);
|
||||
Assert.assertEquals(serializableBean1, serializableBean2);
|
||||
|
||||
final Bean bean1 = new Bean(3);
|
||||
Assert.assertNull(ObjUtil.clone(bean1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cloneIfPossibleTest() {
|
||||
Assert.assertNull(ObjUtil.clone(null));
|
||||
|
||||
final CloneableBean cloneableBean1 = new CloneableBean(1);
|
||||
Assert.assertEquals(cloneableBean1, ObjUtil.cloneIfPossible(cloneableBean1));
|
||||
|
||||
final SerializableBean serializableBean1 = new SerializableBean(2);
|
||||
Assert.assertEquals(serializableBean1, ObjUtil.cloneIfPossible(serializableBean1));
|
||||
|
||||
final Bean bean1 = new Bean(3);
|
||||
Assert.assertSame(bean1, ObjUtil.cloneIfPossible(bean1));
|
||||
|
||||
final ExceptionCloneableBean exceptionBean1 = new ExceptionCloneableBean(3);
|
||||
Assert.assertSame(exceptionBean1, ObjUtil.cloneIfPossible(exceptionBean1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cloneByStreamTest() {
|
||||
Assert.assertNull(ObjUtil.cloneByStream(null));
|
||||
Assert.assertNull(ObjUtil.cloneByStream(new CloneableBean(1)));
|
||||
final SerializableBean serializableBean1 = new SerializableBean(2);
|
||||
Assert.assertEquals(serializableBean1, ObjUtil.cloneByStream(serializableBean1));
|
||||
Assert.assertNull(ObjUtil.cloneByStream(new Bean(1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isBasicTypeTest(){
|
||||
final int a = 1;
|
||||
@@ -121,9 +175,72 @@ public class ObjUtilTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cloneIfPossibleTest() {
|
||||
final String a = "a";
|
||||
final String a2 = ObjUtil.cloneIfPossible(a);
|
||||
Assert.assertNotSame(a, a2);
|
||||
public void isValidIfNumberTest() {
|
||||
Assert.assertTrue(ObjUtil.isValidIfNumber(null));
|
||||
Assert.assertFalse(ObjUtil.isValidIfNumber(Double.NEGATIVE_INFINITY));
|
||||
Assert.assertFalse(ObjUtil.isValidIfNumber(Double.NaN));
|
||||
Assert.assertTrue(ObjUtil.isValidIfNumber(Double.MIN_VALUE));
|
||||
Assert.assertFalse(ObjUtil.isValidIfNumber(Float.NEGATIVE_INFINITY));
|
||||
Assert.assertFalse(ObjUtil.isValidIfNumber(Float.NaN));
|
||||
Assert.assertTrue(ObjUtil.isValidIfNumber(Float.MIN_VALUE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compareTest() {
|
||||
Assert.assertEquals(0, ObjUtil.compare(1, 1));
|
||||
Assert.assertEquals(1, ObjUtil.compare(1, null));
|
||||
Assert.assertEquals(-1, ObjUtil.compare(null, 1));
|
||||
|
||||
Assert.assertEquals(-1, ObjUtil.compare(1, null, true));
|
||||
Assert.assertEquals(1, ObjUtil.compare(null, 1, true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getTypeArgumentTest() {
|
||||
final Bean bean = new Bean(1);
|
||||
Assert.assertEquals(Integer.class, ObjUtil.getTypeArgument(bean));
|
||||
Assert.assertEquals(String.class, ObjUtil.getTypeArgument(bean, 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toStringTest() {
|
||||
Assert.assertEquals("null", ObjUtil.toString(null));
|
||||
Assert.assertEquals(Collections.emptyMap().toString(), ObjUtil.toString(Collections.emptyMap()));
|
||||
Assert.assertEquals("[1, 2]", Arrays.asList("1", "2").toString());
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
private static class ExceptionCloneableBean implements Cloneable {
|
||||
private final Integer id;
|
||||
@Override
|
||||
protected Object clone() throws CloneNotSupportedException {
|
||||
throw new RuntimeException("can not clone this object");
|
||||
}
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
private static class CloneableBean implements Cloneable {
|
||||
private final Integer id;
|
||||
@Override
|
||||
protected Object clone() throws CloneNotSupportedException {
|
||||
return super.clone();
|
||||
}
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
private static class SerializableBean implements Serializable {
|
||||
private final Integer id;
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
private static class Bean implements TypeArgument<Integer, String> {
|
||||
private final Integer id;
|
||||
}
|
||||
|
||||
private interface TypeArgument<A, B> {};
|
||||
|
||||
}
|
||||
|
||||
@@ -43,4 +43,11 @@ public class RuntimeUtilTest {
|
||||
final int pid = RuntimeUtil.getPid();
|
||||
Assert.assertTrue(pid > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getProcessorCountTest(){
|
||||
int cpu = RuntimeUtil.getProcessorCount();
|
||||
Console.log("cpu个数:{}", cpu);
|
||||
Assert.assertTrue(cpu > 0);
|
||||
}
|
||||
}
|
||||
|
||||
3
hutool-core/src/test/resources/text.txt
Normal file
3
hutool-core/src/test/resources/text.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
is first line
|
||||
is second line
|
||||
is third line
|
||||
Reference in New Issue
Block a user