add ListUtil

This commit is contained in:
Looly 2020-03-25 17:49:25 +08:00
parent 5443f028bd
commit 8c9abbe3e3
8 changed files with 591 additions and 185 deletions

View File

@ -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

View File

@ -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>
* 两个集合无差集则返回空集合
*
@ -232,6 +237,24 @@ public class CollUtil {
return result;
}
/**
* 计算集合的单差集即只返回集合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}
*
@ -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
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -121,6 +121,15 @@ public class CollUtilTest {
Assert.assertTrue(disjunction2.contains("c"));
}
@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<>();
@ -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);