Looly 5 年 前
コミット
8c9abbe3e3

+ 2 - 0
CHANGELOG.md

@@ -13,6 +13,8 @@
 * 【cache  】     修改FIFOCache中linkedHashMap的初始容量策略(pr#801@Github)
 * 【core   】     修改XmlUtil中setNamespaceAware默认为true
 * 【core   】     TreeNode增加extra
+* 【core   】     CollUtil.newHashSet重载歧义,更换为set方法
+* 【core   】     增加ListUtil,增加Hash32、Hash64、Hash128接口
 
 ### Bug修复
 * 【core   】     修复NumberWordFormatter拼写错误(issue#799@Github)

+ 67 - 168
hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java

@@ -9,12 +9,12 @@ import cn.hutool.core.exceptions.UtilException;
 import cn.hutool.core.lang.Editor;
 import cn.hutool.core.lang.Filter;
 import cn.hutool.core.lang.Matcher;
+import cn.hutool.core.lang.hash.Hash32;
 import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.ArrayUtil;
 import cn.hutool.core.util.CharUtil;
 import cn.hutool.core.util.ClassUtil;
 import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.PageUtil;
 import cn.hutool.core.util.ReflectUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.core.util.TypeUtil;
@@ -199,8 +199,13 @@ public class CollUtil {
 	/**
 	 * 两个集合的差集<br>
 	 * 针对一个集合中存在多个相同元素的情况,计算两个集合中此元素的个数,保留两个集合中此元素个数差的个数<br>
-	 * 例如:集合1:[a, b, c, c, c],集合2:[a, b, c, c]<br>
-	 * 结果:[c],此结果中只保留了一个<br>
+	 * 例如:
+	 *
+	 * <pre>
+	 *     disjunction([a, b, c, c, c], [a, b, c, c]) -》 [c]
+	 *     disjunction([a, b], [])                    -》 [a, b]
+	 *     disjunction([a, b, c], [b, c, d])          -》 [a, d]
+	 * </pre>
 	 * 任意一个集合为空,返回另一个集合<br>
 	 * 两个集合无差集则返回空集合
 	 *
@@ -233,6 +238,24 @@ public class CollUtil {
 	}
 
 	/**
+	 * 计算集合的单差集,即只返回【集合1】中有,但是【集合2】中没有的元素,例如:
+	 *
+	 * <pre>
+	 *     subtract([1,2,3,4],[2,3,4,5]) -》 [1]
+	 * </pre>
+	 *
+	 * @param coll1 集合1
+	 * @param coll2 集合2
+	 * @param <T> 元素类型
+	 * @return 单差集
+	 */
+	public static <T> Collection<T> subtract(Collection<T> coll1, Collection<T> coll2) {
+		final Collection<T> result = ObjectUtil.clone(coll1);
+		result.removeAll(coll2);
+		return result;
+	}
+
+	/**
 	 * 判断指定集合是否包含指定值,如果集合为空(null或者空),返回{@code false},否则找到元素返回{@code true}
 	 *
 	 * @param collection 集合
@@ -450,7 +473,7 @@ public class CollUtil {
 	 */
 	@SafeVarargs
 	public static <T> HashSet<T> newHashSet(T... ts) {
-		return newHashSet(false, ts);
+		return set(false, ts);
 	}
 
 	/**
@@ -475,7 +498,7 @@ public class CollUtil {
 	 * @return HashSet对象
 	 */
 	@SafeVarargs
-	public static <T> HashSet<T> newHashSet(boolean isSorted, T... ts) {
+	public static <T> HashSet<T> set(boolean isSorted, T... ts) {
 		if (null == ts) {
 			return isSorted ? new LinkedHashSet<>() : new HashSet<>();
 		}
@@ -519,7 +542,7 @@ public class CollUtil {
 	 */
 	public static <T> HashSet<T> newHashSet(boolean isSorted, Iterator<T> iter) {
 		if (null == iter) {
-			return newHashSet(isSorted, (T[]) null);
+			return set(isSorted, (T[]) null);
 		}
 		final HashSet<T> set = isSorted ? new LinkedHashSet<>() : new HashSet<>();
 		while (iter.hasNext()) {
@@ -539,7 +562,7 @@ public class CollUtil {
 	 */
 	public static <T> HashSet<T> newHashSet(boolean isSorted, Enumeration<T> enumeration) {
 		if (null == enumeration) {
-			return newHashSet(isSorted, (T[]) null);
+			return set(isSorted, (T[]) null);
 		}
 		final HashSet<T> set = isSorted ? new LinkedHashSet<>() : new HashSet<>();
 		while (enumeration.hasMoreElements()) {
@@ -559,7 +582,7 @@ public class CollUtil {
 	 * @since 4.1.2
 	 */
 	public static <T> List<T> list(boolean isLinked) {
-		return isLinked ? new LinkedList<>() : new ArrayList<>();
+		return ListUtil.list(isLinked);
 	}
 
 	/**
@@ -573,12 +596,7 @@ public class CollUtil {
 	 */
 	@SafeVarargs
 	public static <T> List<T> list(boolean isLinked, T... values) {
-		if (ArrayUtil.isEmpty(values)) {
-			return list(isLinked);
-		}
-		final List<T> arrayList = isLinked ? new LinkedList<>() : new ArrayList<>(values.length);
-		Collections.addAll(arrayList, values);
-		return arrayList;
+		return ListUtil.list(isLinked, values);
 	}
 
 	/**
@@ -591,10 +609,7 @@ public class CollUtil {
 	 * @since 4.1.2
 	 */
 	public static <T> List<T> list(boolean isLinked, Collection<T> collection) {
-		if (null == collection) {
-			return list(isLinked);
-		}
-		return isLinked ? new LinkedList<>(collection) : new ArrayList<>(collection);
+		return ListUtil.list(isLinked, collection);
 	}
 
 	/**
@@ -608,10 +623,7 @@ public class CollUtil {
 	 * @since 4.1.2
 	 */
 	public static <T> List<T> list(boolean isLinked, Iterable<T> iterable) {
-		if (null == iterable) {
-			return list(isLinked);
-		}
-		return list(isLinked, iterable.iterator());
+		return ListUtil.list(isLinked, iterable);
 	}
 
 	/**
@@ -625,13 +637,7 @@ public class CollUtil {
 	 * @since 4.1.2
 	 */
 	public static <T> List<T> list(boolean isLinked, Iterator<T> iter) {
-		final List<T> list = list(isLinked);
-		if (null != iter) {
-			while (iter.hasNext()) {
-				list.add(iter.next());
-			}
-		}
-		return list;
+		return ListUtil.list(isLinked, iter);
 	}
 
 	/**
@@ -640,18 +646,12 @@ public class CollUtil {
 	 *
 	 * @param <T>        集合元素类型
 	 * @param isLinked   是否新建LinkedList
-	 * @param enumration {@link Enumeration}
+	 * @param enumeration {@link Enumeration}
 	 * @return ArrayList对象
 	 * @since 3.0.8
 	 */
-	public static <T> List<T> list(boolean isLinked, Enumeration<T> enumration) {
-		final List<T> list = list(isLinked);
-		if (null != enumration) {
-			while (enumration.hasMoreElements()) {
-				list.add(enumration.nextElement());
-			}
-		}
-		return list;
+	public static <T> List<T> list(boolean isLinked, Enumeration<T> enumeration) {
+		return ListUtil.list(isLinked, enumeration);
 	}
 
 	/**
@@ -660,10 +660,11 @@ public class CollUtil {
 	 * @param <T>    集合元素类型
 	 * @param values 数组
 	 * @return ArrayList对象
+	 * @see #toList(Object[])
 	 */
 	@SafeVarargs
 	public static <T> ArrayList<T> newArrayList(T... values) {
-		return (ArrayList<T>) list(false, values);
+		return ListUtil.toList(values);
 	}
 
 	/**
@@ -676,7 +677,7 @@ public class CollUtil {
 	 */
 	@SafeVarargs
 	public static <T> ArrayList<T> toList(T... values) {
-		return newArrayList(values);
+		return ListUtil.toList(values);
 	}
 
 	/**
@@ -687,7 +688,7 @@ public class CollUtil {
 	 * @return ArrayList对象
 	 */
 	public static <T> ArrayList<T> newArrayList(Collection<T> collection) {
-		return (ArrayList<T>) list(false, collection);
+		return ListUtil.toList(collection);
 	}
 
 	/**
@@ -700,7 +701,7 @@ public class CollUtil {
 	 * @since 3.1.0
 	 */
 	public static <T> ArrayList<T> newArrayList(Iterable<T> iterable) {
-		return (ArrayList<T>) list(false, iterable);
+		return ListUtil.toList(iterable);
 	}
 
 	/**
@@ -708,12 +709,12 @@ public class CollUtil {
 	 * 提供的参数为null时返回空{@link ArrayList}
 	 *
 	 * @param <T>  集合元素类型
-	 * @param iter {@link Iterator}
+	 * @param iterator {@link Iterator}
 	 * @return ArrayList对象
 	 * @since 3.0.8
 	 */
-	public static <T> ArrayList<T> newArrayList(Iterator<T> iter) {
-		return (ArrayList<T>) list(false, iter);
+	public static <T> ArrayList<T> newArrayList(Iterator<T> iterator) {
+		return ListUtil.toList(iterator);
 	}
 
 	/**
@@ -721,12 +722,12 @@ public class CollUtil {
 	 * 提供的参数为null时返回空{@link ArrayList}
 	 *
 	 * @param <T>        集合元素类型
-	 * @param enumration {@link Enumeration}
+	 * @param enumeration {@link Enumeration}
 	 * @return ArrayList对象
 	 * @since 3.0.8
 	 */
-	public static <T> ArrayList<T> newArrayList(Enumeration<T> enumration) {
-		return (ArrayList<T>) list(false, enumration);
+	public static <T> ArrayList<T> newArrayList(Enumeration<T> enumeration) {
+		return ListUtil.toList(enumeration);
 	}
 
 	// ----------------------------------------------------------------------new LinkedList
@@ -741,7 +742,7 @@ public class CollUtil {
 	 */
 	@SafeVarargs
 	public static <T> LinkedList<T> newLinkedList(T... values) {
-		return (LinkedList<T>) list(true, values);
+		return ListUtil.toLinkedList(values);
 	}
 
 	/**
@@ -752,7 +753,7 @@ public class CollUtil {
 	 * @return {@link CopyOnWriteArrayList}
 	 */
 	public static <T> CopyOnWriteArrayList<T> newCopyOnWriteArrayList(Collection<T> collection) {
-		return (null == collection) ? (new CopyOnWriteArrayList<>()) : (new CopyOnWriteArrayList<>(collection));
+		return ListUtil.toCopyOnWriteArrayList(collection);
 	}
 
 	/**
@@ -862,7 +863,7 @@ public class CollUtil {
 	 * @return 截取后的数组,当开始位置超过最大时,返回空的List
 	 */
 	public static <T> List<T> sub(List<T> list, int start, int end) {
-		return sub(list, start, end, 1);
+		return ListUtil.sub(list, start, end);
 	}
 
 	/**
@@ -877,45 +878,7 @@ public class CollUtil {
 	 * @since 4.0.6
 	 */
 	public static <T> List<T> sub(List<T> list, int start, int end, int step) {
-		if (list == null) {
-			return null;
-		}
-
-		if (list.isEmpty()) {
-			return new ArrayList<>(0);
-		}
-
-		final int size = list.size();
-		if (start < 0) {
-			start += size;
-		}
-		if (end < 0) {
-			end += size;
-		}
-		if (start == size) {
-			return new ArrayList<>(0);
-		}
-		if (start > end) {
-			int tmp = start;
-			start = end;
-			end = tmp;
-		}
-		if (end > size) {
-			if (start >= size) {
-				return new ArrayList<>(0);
-			}
-			end = size;
-		}
-
-		if (step <= 1) {
-			return list.subList(start, end);
-		}
-
-		final List<T> result = new ArrayList<>();
-		for (int i = start; i < end; i += step) {
-			result.add(list.get(i));
-		}
-		return result;
+		return ListUtil.sub(list, start, end, step);
 	}
 
 	/**
@@ -1026,19 +989,7 @@ public class CollUtil {
 	 * @since 4.1.8
 	 */
 	public static <T> List<T> filter(List<T> list, Editor<T> editor) {
-		if (null == list || null == editor) {
-			return list;
-		}
-
-		final List<T> list2 = (list instanceof LinkedList) ? new LinkedList<>() : new ArrayList<>(list.size());
-		T modified;
-		for (T t : list) {
-			modified = editor.edit(t);
-			if (null != modified) {
-				list2.add(modified);
-			}
-		}
-		return list2;
+		return ListUtil.filter(list, editor);
 	}
 
 	/**
@@ -1091,16 +1042,7 @@ public class CollUtil {
 	 * @since 4.1.8
 	 */
 	public static <T> List<T> filterNew(List<T> list, Filter<T> filter) {
-		if (null == list || null == filter) {
-			return list;
-		}
-		final List<T> list2 = (list instanceof LinkedList) ? new LinkedList<>() : new ArrayList<>(list.size());
-		for (T t : list) {
-			if (filter.accept(t)) {
-				list2.add(t);
-			}
-		}
-		return list2;
+		return ListUtil.filter(list, t -> filter.accept(t) ? t : null);
 	}
 
 	/**
@@ -2121,25 +2063,7 @@ public class CollUtil {
 	 * @since 4.1.20
 	 */
 	public static <T> List<T> page(int pageNo, int pageSize, List<T> list) {
-		if (isEmpty(list)) {
-			return new ArrayList<>(0);
-		}
-
-		int resultSize = list.size();
-		// 每页条目数大于总数直接返回所有
-		if (resultSize <= pageSize) {
-			if (pageNo < 1) {
-				return Collections.unmodifiableList(list);
-			} else {
-				// 越界直接返回空
-				return new ArrayList<>(0);
-			}
-		}
-		final int[] startEnd = PageUtil.transToStartEnd(pageNo, pageSize);
-		if (startEnd[1] > resultSize) {
-			startEnd[1] = resultSize;
-		}
-		return list.subList(startEnd[0], startEnd[1]);
+		return ListUtil.page(pageNo, pageSize, list);
 	}
 
 	/**
@@ -2166,8 +2090,7 @@ public class CollUtil {
 	 * @see Collections#sort(List, Comparator)
 	 */
 	public static <T> List<T> sort(List<T> list, Comparator<? super T> c) {
-		list.sort(c);
-		return list;
+		return ListUtil.sort(list, c);
 	}
 
 	/**
@@ -2193,7 +2116,7 @@ public class CollUtil {
 	 * @since 4.0.6
 	 */
 	public static <T> List<T> sortByProperty(List<T> list, String property) {
-		return sort(list, new PropertyComparator<>(property));
+		return ListUtil.sortByProperty(list, property);
 	}
 
 	/**
@@ -2215,7 +2138,7 @@ public class CollUtil {
 	 * @since 4.0.8
 	 */
 	public static List<String> sortByPinyin(List<String> list) {
-		return sort(list, new PinyinComparator());
+		return ListUtil.sortByPinyin(list);
 	}
 
 	/**
@@ -2342,14 +2265,14 @@ public class CollUtil {
 	}
 
 	/**
-	 * 分组,按照{@link Hash}接口定义的hash算法,集合中的元素放入hash值对应的子列表中
+	 * 分组,按照{@link Hash32}接口定义的hash算法,集合中的元素放入hash值对应的子列表中
 	 *
 	 * @param <T>        元素类型
 	 * @param collection 被分组的集合
 	 * @param hash       Hash值算法,决定元素放在第几个分组的规则
 	 * @return 分组后的集合
 	 */
-	public static <T> List<List<T>> group(Collection<T> collection, Hash<T> hash) {
+	public static <T> List<List<T>> group(Collection<T> collection, Hash32<T> hash) {
 		final List<List<T>> result = new ArrayList<>();
 		if (isEmpty(collection)) {
 			return result;
@@ -2362,7 +2285,7 @@ public class CollUtil {
 		int index;
 		List<T> subList;
 		for (T t : collection) {
-			index = hash.hash(t);
+			index = hash.hash32(t);
 			if (result.size() - 1 < index) {
 				while (result.size() - 1 < index) {
 					result.add(null);
@@ -2389,11 +2312,11 @@ public class CollUtil {
 	 * @return 分组列表
 	 */
 	public static <T> List<List<T>> groupByField(Collection<T> collection, final String fieldName) {
-		return group(collection, new Hash<T>() {
+		return group(collection, new Hash32<T>() {
 			private final List<Object> fieldNameList = new ArrayList<>();
 
 			@Override
-			public int hash(T t) {
+			public int hash32(T t) {
 				if (null == t || false == BeanUtil.isBean(t.getClass())) {
 					// 非Bean放在同一子分组中
 					return 0;
@@ -2419,8 +2342,7 @@ public class CollUtil {
 	 * @since 4.0.6
 	 */
 	public static <T> List<T> reverse(List<T> list) {
-		Collections.reverse(list);
-		return list;
+		return ListUtil.reverse(list);
 	}
 
 	/**
@@ -2432,8 +2354,7 @@ public class CollUtil {
 	 * @since 4.0.6
 	 */
 	public static <T> List<T> reverseNew(List<T> list) {
-		final List<T> list2 = ObjectUtil.clone(list);
-		return reverse(list2);
+		return ListUtil.reverseNew(list);
 	}
 
 	/**
@@ -2447,12 +2368,7 @@ public class CollUtil {
 	 * @since 4.1.2
 	 */
 	public static <T> List<T> setOrAppend(List<T> list, int index, T element) {
-		if (index < list.size()) {
-			list.set(index, element);
-		} else {
-			list.add(element);
-		}
-		return list;
+		return ListUtil.setOrAppend(list, index, element);
 	}
 
 	/**
@@ -2553,22 +2469,5 @@ public class CollUtil {
 		 */
 		void accept(K key, V value, int index);
 	}
-
-	/**
-	 * Hash计算接口
-	 *
-	 * @param <T> 被计算hash的对象类型
-	 * @author looly
-	 * @since 3.2.2
-	 */
-	public interface Hash<T> {
-		/**
-		 * 计算Hash值
-		 *
-		 * @param t 对象
-		 * @return hash
-		 */
-		int hash(T t);
-	}
 	// ---------------------------------------------------------------------------------------------- Interface end
 }

+ 448 - 0
hutool-core/src/main/java/cn/hutool/core/collection/ListUtil.java

@@ -0,0 +1,448 @@
+package cn.hutool.core.collection;
+
+import cn.hutool.core.comparator.PinyinComparator;
+import cn.hutool.core.comparator.PropertyComparator;
+import cn.hutool.core.lang.Editor;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.PageUtil;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+public class ListUtil {
+	/**
+	 * 新建一个空List
+	 *
+	 * @param <T>      集合元素类型
+	 * @param isLinked 是否新建LinkedList
+	 * @return List对象
+	 * @since 4.1.2
+	 */
+	public static <T> List<T> list(boolean isLinked) {
+		return isLinked ? new LinkedList<>() : new ArrayList<>();
+	}
+
+	/**
+	 * 新建一个List
+	 *
+	 * @param <T>      集合元素类型
+	 * @param isLinked 是否新建LinkedList
+	 * @param values   数组
+	 * @return List对象
+	 * @since 4.1.2
+	 */
+	@SafeVarargs
+	public static <T> List<T> list(boolean isLinked, T... values) {
+		if (ArrayUtil.isEmpty(values)) {
+			return list(isLinked);
+		}
+		final List<T> arrayList = isLinked ? new LinkedList<>() : new ArrayList<>(values.length);
+		Collections.addAll(arrayList, values);
+		return arrayList;
+	}
+
+	/**
+	 * 新建一个List
+	 *
+	 * @param <T>        集合元素类型
+	 * @param isLinked   是否新建LinkedList
+	 * @param collection 集合
+	 * @return List对象
+	 * @since 4.1.2
+	 */
+	public static <T> List<T> list(boolean isLinked, Collection<T> collection) {
+		if (null == collection) {
+			return list(isLinked);
+		}
+		return isLinked ? new LinkedList<>(collection) : new ArrayList<>(collection);
+	}
+
+	/**
+	 * 新建一个List<br>
+	 * 提供的参数为null时返回空{@link ArrayList}
+	 *
+	 * @param <T>      集合元素类型
+	 * @param isLinked 是否新建LinkedList
+	 * @param iterable {@link Iterable}
+	 * @return List对象
+	 * @since 4.1.2
+	 */
+	public static <T> List<T> list(boolean isLinked, Iterable<T> iterable) {
+		if (null == iterable) {
+			return list(isLinked);
+		}
+		return list(isLinked, iterable.iterator());
+	}
+
+	/**
+	 * 新建一个ArrayList<br>
+	 * 提供的参数为null时返回空{@link ArrayList}
+	 *
+	 * @param <T>      集合元素类型
+	 * @param isLinked 是否新建LinkedList
+	 * @param iter     {@link Iterator}
+	 * @return ArrayList对象
+	 * @since 4.1.2
+	 */
+	public static <T> List<T> list(boolean isLinked, Iterator<T> iter) {
+		final List<T> list = list(isLinked);
+		if (null != iter) {
+			while (iter.hasNext()) {
+				list.add(iter.next());
+			}
+		}
+		return list;
+	}
+
+	/**
+	 * 新建一个List<br>
+	 * 提供的参数为null时返回空{@link ArrayList}
+	 *
+	 * @param <T>        集合元素类型
+	 * @param isLinked   是否新建LinkedList
+	 * @param enumration {@link Enumeration}
+	 * @return ArrayList对象
+	 * @since 3.0.8
+	 */
+	public static <T> List<T> list(boolean isLinked, Enumeration<T> enumration) {
+		final List<T> list = list(isLinked);
+		if (null != enumration) {
+			while (enumration.hasMoreElements()) {
+				list.add(enumration.nextElement());
+			}
+		}
+		return list;
+	}
+
+	/**
+	 * 新建一个ArrayList
+	 *
+	 * @param <T>    集合元素类型
+	 * @param values 数组
+	 * @return ArrayList对象
+	 */
+	@SafeVarargs
+	public static <T> ArrayList<T> toList(T... values) {
+		return (ArrayList<T>) list(false, values);
+	}
+
+	/**
+	 * 新建LinkedList
+	 *
+	 * @param values 数组
+	 * @param <T>    类型
+	 * @return LinkedList
+	 * @since 4.1.2
+	 */
+	@SafeVarargs
+	public static <T> LinkedList<T> toLinkedList(T... values) {
+		return (LinkedList<T>) list(true, values);
+	}
+
+	/**
+	 * 新建一个CopyOnWriteArrayList
+	 *
+	 * @param <T>        集合元素类型
+	 * @param collection 集合
+	 * @return {@link CopyOnWriteArrayList}
+	 */
+	public static <T> CopyOnWriteArrayList<T> toCopyOnWriteArrayList(Collection<T> collection) {
+		return (null == collection) ? (new CopyOnWriteArrayList<>()) : (new CopyOnWriteArrayList<>(collection));
+	}
+
+	/**
+	 * 新建一个ArrayList
+	 *
+	 * @param <T>        集合元素类型
+	 * @param collection 集合
+	 * @return ArrayList对象
+	 */
+	public static <T> ArrayList<T> toList(Collection<T> collection) {
+		return (ArrayList<T>) list(false, collection);
+	}
+
+	/**
+	 * 新建一个ArrayList<br>
+	 * 提供的参数为null时返回空{@link ArrayList}
+	 *
+	 * @param <T>      集合元素类型
+	 * @param iterable {@link Iterable}
+	 * @return ArrayList对象
+	 * @since 3.1.0
+	 */
+	public static <T> ArrayList<T> toList(Iterable<T> iterable) {
+		return (ArrayList<T>) list(false, iterable);
+	}
+
+	/**
+	 * 新建一个ArrayList<br>
+	 * 提供的参数为null时返回空{@link ArrayList}
+	 *
+	 * @param <T>      集合元素类型
+	 * @param iterator {@link Iterator}
+	 * @return ArrayList对象
+	 * @since 3.0.8
+	 */
+	public static <T> ArrayList<T> toList(Iterator<T> iterator) {
+		return (ArrayList<T>) list(false, iterator);
+	}
+
+	/**
+	 * 新建一个ArrayList<br>
+	 * 提供的参数为null时返回空{@link ArrayList}
+	 *
+	 * @param <T>         集合元素类型
+	 * @param enumeration {@link Enumeration}
+	 * @return ArrayList对象
+	 * @since 3.0.8
+	 */
+	public static <T> ArrayList<T> toList(Enumeration<T> enumeration) {
+		return (ArrayList<T>) list(false, enumeration);
+	}
+
+	/**
+	 * 对指定List分页取值
+	 *
+	 * @param <T>      集合元素类型
+	 * @param pageNo   页码,从0开始计数,0表示第一页
+	 * @param pageSize 每页的条目数
+	 * @param list     列表
+	 * @return 分页后的段落内容
+	 * @since 4.1.20
+	 */
+	public static <T> List<T> page(int pageNo, int pageSize, List<T> list) {
+		if (CollUtil.isEmpty(list)) {
+			return new ArrayList<>(0);
+		}
+
+		int resultSize = list.size();
+		// 每页条目数大于总数直接返回所有
+		if (resultSize <= pageSize) {
+			if (pageNo < 1) {
+				return Collections.unmodifiableList(list);
+			} else {
+				// 越界直接返回空
+				return new ArrayList<>(0);
+			}
+		}
+		final int[] startEnd = PageUtil.transToStartEnd(pageNo, pageSize);
+		if (startEnd[1] > resultSize) {
+			startEnd[1] = resultSize;
+		}
+		return list.subList(startEnd[0], startEnd[1]);
+	}
+
+	/**
+	 * 针对List排序,排序会修改原List
+	 *
+	 * @param <T>  元素类型
+	 * @param list 被排序的List
+	 * @param c    {@link Comparator}
+	 * @return 原list
+	 * @see Collections#sort(List, Comparator)
+	 */
+	public static <T> List<T> sort(List<T> list, Comparator<? super T> c) {
+		list.sort(c);
+		return list;
+	}
+
+	/**
+	 * 根据Bean的属性排序
+	 *
+	 * @param <T>      元素类型
+	 * @param list     List
+	 * @param property 属性名
+	 * @return 排序后的List
+	 * @since 4.0.6
+	 */
+	public static <T> List<T> sortByProperty(List<T> list, String property) {
+		return sort(list, new PropertyComparator<>(property));
+	}
+
+	/**
+	 * 根据汉字的拼音顺序排序
+	 *
+	 * @param list List
+	 * @return 排序后的List
+	 * @since 4.0.8
+	 */
+	public static List<String> sortByPinyin(List<String> list) {
+		return sort(list, new PinyinComparator());
+	}
+
+	/**
+	 * 反序给定List,会在原List基础上直接修改
+	 *
+	 * @param <T>  元素类型
+	 * @param list 被反转的List
+	 * @return 反转后的List
+	 * @since 4.0.6
+	 */
+	public static <T> List<T> reverse(List<T> list) {
+		Collections.reverse(list);
+		return list;
+	}
+
+	/**
+	 * 反序给定List,会创建一个新的List,原List数据不变
+	 *
+	 * @param <T>  元素类型
+	 * @param list 被反转的List
+	 * @return 反转后的List
+	 * @since 4.0.6
+	 */
+	public static <T> List<T> reverseNew(List<T> list) {
+		final List<T> list2 = ObjectUtil.clone(list);
+		return reverse(list2);
+	}
+
+	/**
+	 * 设置或增加元素。当index小于List的长度时,替换指定位置的值,否则在尾部追加
+	 *
+	 * @param <T>     元素类型
+	 * @param list    List列表
+	 * @param index   位置
+	 * @param element 新元素
+	 * @return 原List
+	 * @since 4.1.2
+	 */
+	public static <T> List<T> setOrAppend(List<T> list, int index, T element) {
+		if (index < list.size()) {
+			list.set(index, element);
+		} else {
+			list.add(element);
+		}
+		return list;
+	}
+
+	/**
+	 * 截取集合的部分
+	 *
+	 * @param <T>   集合元素类型
+	 * @param list  被截取的数组
+	 * @param start 开始位置(包含)
+	 * @param end   结束位置(不包含)
+	 * @return 截取后的数组,当开始位置超过最大时,返回空的List
+	 */
+	public static <T> List<T> sub(List<T> list, int start, int end) {
+		return sub(list, start, end, 1);
+	}
+
+	/**
+	 * 截取集合的部分
+	 *
+	 * @param <T>   集合元素类型
+	 * @param list  被截取的数组
+	 * @param start 开始位置(包含)
+	 * @param end   结束位置(不包含)
+	 * @param step  步进
+	 * @return 截取后的数组,当开始位置超过最大时,返回空的List
+	 * @since 4.0.6
+	 */
+	public static <T> List<T> sub(List<T> list, int start, int end, int step) {
+		if (list == null) {
+			return null;
+		}
+
+		if (list.isEmpty()) {
+			return new ArrayList<>(0);
+		}
+
+		final int size = list.size();
+		if (start < 0) {
+			start += size;
+		}
+		if (end < 0) {
+			end += size;
+		}
+		if (start == size) {
+			return new ArrayList<>(0);
+		}
+		if (start > end) {
+			int tmp = start;
+			start = end;
+			end = tmp;
+		}
+		if (end > size) {
+			if (start >= size) {
+				return new ArrayList<>(0);
+			}
+			end = size;
+		}
+
+		if (step <= 1) {
+			return list.subList(start, end);
+		}
+
+		final List<T> result = new ArrayList<>();
+		for (int i = start; i < end; i += step) {
+			result.add(list.get(i));
+		}
+		return result;
+	}
+
+	/**
+	 * 编辑列表,此方法会修改原列表的内容<br>
+	 * 编辑过程通过传入的Editor实现编辑列表中元素内容,这个Editor实现可以实现以下功能:
+	 *
+	 * <pre>
+	 *  1、修改元素对象,返回集合中为修改后的对象
+	 * </pre>
+	 *
+	 * @param <T>    集合元素类型
+	 * @param list   集合
+	 * @param editor 编辑器接口
+	 * @return 编辑后的数组
+	 * @since 4.1.8
+	 */
+	public static <T> List<T> edit(List<T> list, Editor<T> editor) {
+		if (null == list || null == editor) {
+			return list;
+		}
+
+		for (T t : list) {
+			editor.edit(t);
+		}
+
+		return list;
+	}
+
+	/**
+	 * 过滤<br>
+	 * 过滤过程通过传入的Editor实现来返回需要的元素内容,这个Editor实现可以实现以下功能:
+	 *
+	 * <pre>
+	 * 1、过滤出需要的对象,如果返回null表示这个元素对象抛弃
+	 * 2、修改元素对象,返回集合中为修改后的对象
+	 * </pre>
+	 *
+	 * @param <T>    集合元素类型
+	 * @param list   集合
+	 * @param editor 编辑器接口
+	 * @return 过滤后的数组
+	 * @since 4.1.8
+	 */
+	public static <T> List<T> filter(List<T> list, Editor<T> editor) {
+		if (null == list || null == editor) {
+			return list;
+		}
+
+		final List<T> list2 = (list instanceof LinkedList) ? new LinkedList<>() : new ArrayList<>(list.size());
+		T modified;
+		for (T t : list) {
+			modified = editor.edit(t);
+			if (null != modified) {
+				list2.add(modified);
+			}
+		}
+		return list2;
+	}
+}

+ 7 - 15
hutool-core/src/main/java/cn/hutool/core/lang/ConsistentHash.java

@@ -1,5 +1,6 @@
 package cn.hutool.core.lang;
 
+import cn.hutool.core.lang.hash.Hash32;
 import cn.hutool.core.util.HashUtil;
 
 import java.io.Serializable;
@@ -19,7 +20,7 @@ public class ConsistentHash<T> implements Serializable{
 	private static final long serialVersionUID = 1L;
 	
 	/** Hash计算对象,用于自定义hash算法 */
-	HashFunc hashFunc;
+	Hash32<Object> hashFunc;
 	/** 复制的节点个数 */
 	private final int numberOfReplicas;
 	/** 一致性Hash环 */
@@ -48,7 +49,7 @@ public class ConsistentHash<T> implements Serializable{
 	 * @param numberOfReplicas 复制的节点个数,增加每个节点的复制节点有利于负载均衡
 	 * @param nodes 节点对象
 	 */
-	public ConsistentHash(HashFunc hashFunc, int numberOfReplicas, Collection<T> nodes) {
+	public ConsistentHash(Hash32<Object> hashFunc, int numberOfReplicas, Collection<T> nodes) {
 		this.numberOfReplicas = numberOfReplicas;
 		this.hashFunc = hashFunc;
 		//初始化节点
@@ -66,7 +67,7 @@ public class ConsistentHash<T> implements Serializable{
 	 */
 	public void add(T node) {
 		for (int i = 0; i < numberOfReplicas; i++) {
-			circle.put(hashFunc.hash(node.toString() + i), node);
+			circle.put(hashFunc.hash32(node.toString() + i), node);
 		}
 	}
 
@@ -76,7 +77,7 @@ public class ConsistentHash<T> implements Serializable{
 	 */
 	public void remove(T node) {
 		for (int i = 0; i < numberOfReplicas; i++) {
-			circle.remove(hashFunc.hash(node.toString() + i));
+			circle.remove(hashFunc.hash32(node.toString() + i));
 		}
 	}
 
@@ -89,21 +90,12 @@ public class ConsistentHash<T> implements Serializable{
 		if (circle.isEmpty()) {
 			return null;
 		}
-		int hash = hashFunc.hash(key);
-		if (!circle.containsKey(hash)) {
+		int hash = hashFunc.hash32(key);
+		if (false == circle.containsKey(hash)) {
 			SortedMap<Integer, T> tailMap = circle.tailMap(hash);	//返回此映射的部分视图,其键大于等于 hash
 			hash = tailMap.isEmpty() ? circle.firstKey() : tailMap.firstKey();
 		}
 		//正好命中
 		return circle.get(hash);
 	}
-
-	/**
-	 * Hash算法对象,用于自定义hash算法
-	 * @author xiaoleilu
-	 *
-	 */
-	public interface HashFunc {
-		Integer hash(Object key);
-	}
 }

+ 19 - 0
hutool-core/src/main/java/cn/hutool/core/lang/hash/Hash128.java

@@ -0,0 +1,19 @@
+package cn.hutool.core.lang.hash;
+
+/**
+ * Hash计算接口
+ *
+ * @param <T> 被计算hash的对象类型
+ * @author looly
+ * @since 5.2.5
+ */
+@FunctionalInterface
+public interface Hash128<T> {
+	/**
+	 * 计算Hash值
+	 *
+	 * @param t 对象
+	 * @return hash
+	 */
+	Number128 hash128(T t);
+}

+ 19 - 0
hutool-core/src/main/java/cn/hutool/core/lang/hash/Hash32.java

@@ -0,0 +1,19 @@
+package cn.hutool.core.lang.hash;
+
+/**
+ * Hash计算接口
+ *
+ * @param <T> 被计算hash的对象类型
+ * @author looly
+ * @since 5.2.5
+ */
+@FunctionalInterface
+public interface Hash32<T> {
+	/**
+	 * 计算Hash值
+	 *
+	 * @param t 对象
+	 * @return hash
+	 */
+	int hash32(T t);
+}

+ 19 - 0
hutool-core/src/main/java/cn/hutool/core/lang/hash/Hash64.java

@@ -0,0 +1,19 @@
+package cn.hutool.core.lang.hash;
+
+/**
+ * Hash计算接口
+ *
+ * @param <T> 被计算hash的对象类型
+ * @author looly
+ * @since 5.2.5
+ */
+@FunctionalInterface
+public interface Hash64<T> {
+	/**
+	 * 计算Hash值
+	 *
+	 * @param t 对象
+	 * @return hash
+	 */
+	long hash64(T t);
+}

+ 10 - 2
hutool-core/src/test/java/cn/hutool/core/collection/CollUtilTest.java

@@ -122,6 +122,15 @@ public class CollUtilTest {
 	}
 
 	@Test
+	public void subtractTest(){
+		List<String> list1 = CollUtil.newArrayList("a", "b", "b", "c", "d", "x");
+		List<String> list2 = CollUtil.newArrayList("a", "b", "b", "b", "c", "d", "x2");
+		final Collection<String> subtract = CollUtil.subtract(list1, list2);
+		Assert.assertEquals(1, subtract.size());
+		Assert.assertEquals("x", subtract.iterator().next());
+	}
+
+	@Test
 	public void toMapListAndToListMapTest() {
 		HashMap<String, String> map1 = new HashMap<>();
 		map1.put("a", "值1");
@@ -346,8 +355,7 @@ public class CollUtilTest {
 
 	@Test
 	public void getTest() {
-		@SuppressWarnings("RedundantArrayCreation")
-		HashSet<String> set = CollUtil.newHashSet(true, new String[] { "A", "B", "C", "D" });
+		HashSet<String> set = CollUtil.set(true, "A", "B", "C", "D");
 		String str = CollUtil.get(set, 2);
 		Assert.assertEquals("C", str);