Browse Source

add CollStreamUtil

Looly 5 years ago
parent
commit
01a7b8ddc6

+ 2 - 0
CHANGELOG.md

@@ -7,6 +7,8 @@
 
 ### 新特性
 * 【crypto 】     KeyUtil增加重载,AES构造增加重载(issue#I25NNZ@Gitee)
+* 【json   】     JSONUtil增加toList重载(issue#1228@Github)
+* 【core   】     新增CollStreamUtil(issue#1228@Github)
 
 ### Bug修复
 * 【cron   】     修复CronTimer可能死循环的问题(issue#1224@Github)

+ 196 - 0
hutool-core/src/main/java/cn/hutool/core/collection/CollStreamUtil.java

@@ -0,0 +1,196 @@
+package cn.hutool.core.collection;
+
+
+import cn.hutool.core.map.MapUtil;
+
+import java.util.*;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * 集合的stream操作封装
+ *
+ * @author 528910437@QQ.COM
+ * @since 5.5.2
+ */
+public class CollStreamUtil {
+
+	/**
+	 * 将collection转化为类型不变的map<br>
+	 * <B>{@code Collection<E>  ---->  Map<T,E>}</B>
+	 *
+	 * @param collection 需要转化的集合
+	 * @param key        E类型转化为T类型的lambda方法
+	 * @param <V>        collection中的泛型
+	 * @param <K>        map中的key类型
+	 * @return 转化后的map
+	 */
+	public static <V, K> Map<K, V> toIdentityMap(Collection<V> collection, Function<V, K> key) {
+		if (CollUtil.isEmpty(collection)) {
+			return Collections.emptyMap();
+		}
+		return collection.stream().collect(Collectors.toMap(key, Function.identity()));
+	}
+
+	/**
+	 * 将Collection转化为map(value类型与collection的泛型不同)<br>
+	 * <B>{@code Collection<E> -----> Map<T,U>  }</B>
+	 *
+	 * @param collection 需要转化的集合
+	 * @param key        E类型转化为T类型的lambda方法
+	 * @param value      E类型转化为U类型的lambda方法
+	 * @param <E>        collection中的泛型
+	 * @param <K>        map中的key类型
+	 * @param <V>        map中的value类型
+	 * @return 转化后的map
+	 */
+	public static <E, K, V> Map<K, V> toMap(Collection<E> collection, Function<E, K> key, Function<E, V> value) {
+		if (CollUtil.isEmpty(collection)) {
+			return Collections.emptyMap();
+		}
+		return collection.stream().collect(Collectors.toMap(key, value));
+	}
+
+	/**
+	 * 将collection按照规则(比如有相同的班级id)分类成map<br>
+	 * <B>{@code Collection<E> -------> Map<T,List<E>> } </B>
+	 *
+	 * @param collection 需要分类的集合
+	 * @param key        分类的规则
+	 * @param <E>        collection中的泛型
+	 * @param <K>        map中的key类型
+	 * @return 分类后的map
+	 */
+	public static <E, K> Map<K, List<E>> groupByKey(Collection<E> collection, Function<E, K> key) {
+		if (CollUtil.isEmpty(collection)) {
+			return Collections.emptyMap();
+		}
+		return collection
+				.stream()
+				.collect(Collectors.groupingBy(key, Collectors.toList()));
+	}
+
+	/**
+	 * 将collection按照两个规则(比如有相同的年级id,班级id)分类成双层map<br>
+	 * <B>{@code Collection<E>  --->  Map<T,Map<U,List<E>>> } </B>
+	 *
+	 * @param collection 需要分类的集合
+	 * @param key1       第一个分类的规则
+	 * @param key2       第二个分类的规则
+	 * @param <E>        集合元素类型
+	 * @param <K>        第一个map中的key类型
+	 * @param <U>        第二个map中的key类型
+	 * @return 分类后的map
+	 */
+	public static <E, K, U> Map<K, Map<U, List<E>>> groupBy2Key(Collection<E> collection, Function<E, K> key1, Function<E, U> key2) {
+		if (CollUtil.isEmpty(collection)) {
+			return Collections.emptyMap();
+		}
+		return collection
+				.stream()
+				.collect(Collectors.groupingBy(key1, Collectors.groupingBy(key2, Collectors.toList())));
+	}
+
+	/**
+	 * 将collection按照两个规则(比如有相同的年级id,班级id)分类成双层map
+	 * <br></br>
+	 * <B>{@code Collection<E>  --->  Map<T,Map<U,E>> } </B>
+	 *
+	 * @param collection 需要分类的集合
+	 * @param key1       第一个分类的规则
+	 * @param key2       第二个分类的规则
+	 * @param <T>        第一个map中的key类型
+	 * @param <U>        第二个map中的key类型
+	 * @param <E>        collection中的泛型
+	 * @return 分类后的map
+	 */
+	public static <E, T, U> Map<T, Map<U, E>> group2Map(Collection<E> collection, Function<E, T> key1, Function<E, U> key2) {
+		if (CollUtil.isEmpty(collection) || key1 == null || key2 == null) {
+			return Collections.emptyMap();
+		}
+		return collection
+				.stream()
+				.collect(Collectors.groupingBy(key1, Collectors.toMap(key2, Function.identity())));
+	}
+
+	/**
+	 * 将collection转化为List集合,但是两者的泛型不同
+	 * <br></br>
+	 * <B>{@code Collection<E>  ------>  List<T> } </B>
+	 *
+	 * @param collection 需要转化的集合
+	 * @param function   collection中的泛型转化为list泛型的lambda表达式
+	 * @param <E>        collection中的泛型
+	 * @param <T>        List中的泛型
+	 * @return 转化后的list
+	 */
+	public static <E, T> List<T> toList(Collection<E> collection, Function<E, T> function) {
+		if (CollUtil.isEmpty(collection)) {
+			return Collections.emptyList();
+		}
+		return collection
+				.stream()
+				.map(function)
+				.filter(Objects::nonNull)
+				.collect(Collectors.toList());
+	}
+
+	/**
+	 * 将collection转化为Set集合,但是两者的泛型不同
+	 * <br></br>
+	 * <B>{@code Collection<E>  ------>  Set<T> } </B>
+	 *
+	 * @param collection 需要转化的集合
+	 * @param function   collection中的泛型转化为set泛型的lambda表达式
+	 * @param <E>        collection中的泛型
+	 * @param <T>        Set中的泛型
+	 * @return 转化后的Set
+	 */
+	public static <E, T> Set<T> toSet(Collection<E> collection, Function<E, T> function) {
+		if (CollUtil.isEmpty(collection) || function == null) {
+			return Collections.emptySet();
+		}
+		return collection
+				.stream()
+				.map(function)
+				.filter(Objects::nonNull)
+				.collect(Collectors.toSet());
+	}
+
+
+	/**
+	 * 合并两个相同key类型的map
+	 *
+	 * @param map1  第一个需要合并的 map
+	 * @param map2  第二个需要合并的 map
+	 * @param merge 合并的lambda,将key  value1 value2合并成最终的类型,注意value可能为空的情况
+	 * @param <K>   map中的key类型
+	 * @param <X>   第一个 map的value类型
+	 * @param <Y>   第二个 map的value类型
+	 * @param <V>   最终map的value类型
+	 * @return 合并后的map
+	 */
+	public static <K, X, Y, V> Map<K, V> merge(Map<K, X> map1, Map<K, Y> map2, BiFunction<X, Y, V> merge) {
+		if (MapUtil.isEmpty(map1) && MapUtil.isEmpty(map2)) {
+			return Collections.emptyMap();
+		} else if (MapUtil.isEmpty(map1)) {
+			map1 = Collections.emptyMap();
+		} else if (MapUtil.isEmpty(map2)) {
+			map2 = Collections.emptyMap();
+		}
+		Set<K> key = new HashSet<>();
+		key.addAll(map1.keySet());
+		key.addAll(map2.keySet());
+		Map<K, V> map = new HashMap<>();
+		for (K t : key) {
+			X x = map1.get(t);
+			Y y = map2.get(t);
+			V z = merge.apply(x, y);
+			if (z != null) {
+				map.put(t, z);
+			}
+		}
+		return map;
+	}
+}

+ 0 - 202
hutool-core/src/main/java/cn/hutool/core/collection/CollectionStream.java

@@ -1,202 +0,0 @@
-package cn.hutool.core.collection;
-
-
-import cn.hutool.core.map.MapUtil;
-
-import java.util.*;
-import java.util.function.BiFunction;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
-/**
- * 常用stream操作集合<br></br>
- * 做这个集合的封装的原因在于list.stream后续的写法虽然简便,但是别人看不易不懂,甚至自己写了两周后都看不懂,维护成本高<br></br>
- * 于是笔者采用见名知意的方法封装,降低阅读难度,减轻了维护成本,使用者只需要提供一些简单的lambda表达式<br></br>
- * 当然本人才疏学浅,名字未必能够做到信雅达,欢迎各位大佬指教<br></br>
- * 另外,CollectionStream封装的都是一些常用的stream方法,当然考虑到一些方法不常用(比如map->list),并未提交,如果有一些好的意见,欢迎联系本人528910437@QQ.COM
- *
- * @version 1.0
- */
-public class CollectionStream {
-    /**
-     * 将collection转化为类型不变的map
-     * <br></br>
-     * <B>{@code Collection<E>  ---->  Map<T,E>}</B>
-     *
-     * @param collection 需要转化的集合
-     * @param key        E类型转化为T类型的lambda方法
-     * @param <E>        collection中的泛型
-     * @param <T>        map中的key类型
-     * @return 转化后的map
-     */
-    public static <E, T> Map<T, E> toIdentityMap(Collection<E> collection, Function<E, T> key) {
-        if (CollUtil.isEmpty(collection)) {
-            return Collections.EMPTY_MAP;
-        }
-        return collection.stream().collect(Collectors.toMap(key, Function.identity()));
-    }
-
-    /**
-     * E
-     * 将collection转化为map(value类型与collection的泛型不同)
-     * <br></br>
-     * <B>{@code Collection<E> -----> Map<T,U>  }</B>
-     *
-     * @param collection 需要转化的集合
-     * @param key        E类型转化为T类型的lambda方法
-     * @param value      E类型转化为U类型的lambda方法
-     * @param <E>        collection中的泛型
-     * @param <T>        map中的key类型
-     * @param <U>        map中的value类型
-     * @return 转化后的map
-     */
-    public static <E, T, U> Map<T, U> toMap(Collection<E> collection, Function<E, T> key, Function<E, U> value) {
-        if (CollUtil.isEmpty(collection)) {
-            return Collections.EMPTY_MAP;
-        }
-        return collection.stream().collect(Collectors.toMap(key, value));
-    }
-
-    /**
-     * 将collection按照规则(比如有相同的班级id)分类成map
-     * <br></br>
-     * <B>{@code Collection<E> -------> Map<T,List<E>> } </B>
-     *
-     * @param collection 需要分类的集合
-     * @param key        分类的规则
-     * @param <E>        collection中的泛型
-     * @param <T>        map中的key类型
-     * @return 分类后的map
-     */
-    public static <E, T> Map<T, List<E>> groupByKey(Collection<E> collection, Function<E, T> key) {
-        if (CollUtil.isEmpty(collection)) {
-            return Collections.EMPTY_MAP;
-        }
-        return collection
-                .stream()
-                .collect(Collectors.groupingBy(key, Collectors.toList()));
-    }
-
-    /**
-     * 将collection按照两个规则(比如有相同的年级id,班级id)分类成双层map
-     * <br></br>
-     * <B>{@code Collection<E>  --->  Map<T,Map<U,List<E>>> } </B>
-     *
-     * @param collection 需要分类的集合
-     * @param key1       第一个分类的规则
-     * @param key2       第二个分类的规则
-     * @param <E>        第一个map中的key类型
-     * @param <T>        第二个map中的key类型
-     * @return 分类后的map
-     */
-    public static <E, T, U> Map<T, Map<U, List<E>>> groupBy2Key(Collection<E> collection, Function<E, T> key1, Function<E, U> key2) {
-        if (CollUtil.isEmpty(collection)) {
-            return Collections.EMPTY_MAP;
-        }
-        return collection
-                .stream()
-                .collect(Collectors.groupingBy(key1, Collectors.groupingBy(key2, Collectors.toList())));
-    }
-
-    /**
-     * 将collection按照两个规则(比如有相同的年级id,班级id)分类成双层map
-     * <br></br>
-     * <B>{@code Collection<E>  --->  Map<T,Map<U,E>> } </B>
-     *
-     * @param collection 需要分类的集合
-     * @param key1       第一个分类的规则
-     * @param key2       第二个分类的规则
-     * @param <T>        第一个map中的key类型
-     * @param <U>        第二个map中的key类型
-     * @param <E>        collection中的泛型
-     * @return 分类后的map
-     */
-    public static <E, T, U> Map<T, Map<U, E>> group2Map(Collection<E> collection, Function<E, T> key1, Function<E, U> key2) {
-        if (CollUtil.isEmpty(collection) || key1 == null || key2 == null) {
-            return Collections.EMPTY_MAP;
-        }
-        return collection
-                .stream()
-                .collect(Collectors.groupingBy(key1, Collectors.toMap(key2, Function.identity())));
-    }
-
-    /**
-     * 将collection转化为List集合,但是两者的泛型不同
-     * <br></br>
-     * <B>{@code Collection<E>  ------>  List<T> } </B>
-     *
-     * @param collection 需要转化的集合
-     * @param function   collection中的泛型转化为list泛型的lambda表达式
-     * @param <E>        collection中的泛型
-     * @param <T>        List中的泛型
-     * @return 转化后的list
-     */
-    public static <E, T> List<T> translate2List(Collection<E> collection, Function<E, T> function) {
-        if (CollUtil.isEmpty(collection)) {
-            return Collections.EMPTY_LIST;
-        }
-        return collection
-                .stream()
-                .map(function)
-                .filter(Objects::nonNull)
-                .collect(Collectors.toList());
-    }
-
-    /**
-     * 将collection转化为Set集合,但是两者的泛型不同
-     * <br></br>
-     * <B>{@code Collection<E>  ------>  Set<T> } </B>
-     *
-     * @param collection 需要转化的集合
-     * @param function   collection中的泛型转化为set泛型的lambda表达式
-     * @param <E>        collection中的泛型
-     * @param <T>        Set中的泛型
-     * @return 转化后的Set
-     */
-    public static <E, T> Set<T> translate2Set(Collection<E> collection, Function<E, T> function) {
-        if (CollUtil.isEmpty(collection) || function == null) {
-            return Collections.EMPTY_SET;
-        }
-        return collection
-                .stream()
-                .map(function)
-                .filter(Objects::nonNull)
-                .collect(Collectors.toSet());
-    }
-
-
-    /**
-     * 合并两个相同key类型的map
-     *
-     * @param map1  第一个需要合并的 map
-     * @param map2  第二个需要合并的 map
-     * @param merge 合并的lambda,将key  value1 value2合并成最终的类型,注意value可能为空的情况
-     * @param <T>   map中的key类型
-     * @param <X>   第一个 map的value类型
-     * @param <Y>   第二个 map的value类型
-     * @param <Z>   最终map的value类型
-     * @return 合并后的map
-     */
-    public static <T, X, Y, Z> Map<T, Z> merge(Map<T, X> map1, Map<T, Y> map2, BiFunction<X, Y, Z> merge) {
-        if (MapUtil.isEmpty(map1) && MapUtil.isEmpty(map2)) {
-            return Collections.EMPTY_MAP;
-        } else if (MapUtil.isEmpty(map1)) {
-            map1 = Collections.EMPTY_MAP;
-        } else if (MapUtil.isEmpty(map2)) {
-            map2 = Collections.EMPTY_MAP;
-        }
-        Set<T> key = new HashSet<>();
-        key.addAll(map1.keySet());
-        key.addAll(map2.keySet());
-        Map<T, Z> map = new HashMap<>();
-        for (T t : key) {
-            X x = map1.get(t);
-            Y y = map2.get(t);
-            Z z = merge.apply(x, y);
-            if (z != null) {
-                map.put(t, z);
-            }
-        }
-        return map;
-    }
-}

+ 232 - 0
hutool-core/src/test/java/cn/hutool/core/collection/CollStreamUtilTest.java

@@ -0,0 +1,232 @@
+package cn.hutool.core.collection;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.ToString;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * CollectionStream测试方法
+ */
+public class CollStreamUtilTest {
+	@Test
+	public void testToIdentityMap() {
+		Map<Long, Student> map = CollStreamUtil.toIdentityMap(null, Student::getStudentId);
+		Assert.assertEquals(map, Collections.EMPTY_MAP);
+		List<Student> list = new ArrayList<>();
+		map = CollStreamUtil.toIdentityMap(list, Student::getStudentId);
+		Assert.assertEquals(map, Collections.EMPTY_MAP);
+		list.add(new Student(1, 1, 1, "张三"));
+		list.add(new Student(1, 1, 2, "李四"));
+		list.add(new Student(1, 1, 3, "王五"));
+		map = CollStreamUtil.toIdentityMap(list, Student::getStudentId);
+		Assert.assertEquals(map.get(1L).getName(), "张三");
+		Assert.assertEquals(map.get(2L).getName(), "李四");
+		Assert.assertEquals(map.get(3L).getName(), "王五");
+		Assert.assertNull(map.get(4L));
+	}
+
+	@Test
+	public void testToMap() {
+		Map<Long, String> map = CollStreamUtil.toMap(null, Student::getStudentId, Student::getName);
+		Assert.assertEquals(map, Collections.EMPTY_MAP);
+		List<Student> list = new ArrayList<>();
+		map = CollStreamUtil.toMap(list, Student::getStudentId, Student::getName);
+		Assert.assertEquals(map, Collections.EMPTY_MAP);
+		list.add(new Student(1, 1, 1, "张三"));
+		list.add(new Student(1, 1, 2, "李四"));
+		list.add(new Student(1, 1, 3, "王五"));
+		map = CollStreamUtil.toMap(list, Student::getStudentId, Student::getName);
+		Assert.assertEquals(map.get(1L), "张三");
+		Assert.assertEquals(map.get(2L), "李四");
+		Assert.assertEquals(map.get(3L), "王五");
+		Assert.assertNull(map.get(4L));
+	}
+
+	@Test
+	public void testGroupByKey() {
+		Map<Long, List<Student>> map = CollStreamUtil.groupByKey(null, Student::getClassId);
+		Assert.assertEquals(map, Collections.EMPTY_MAP);
+		List<Student> list = new ArrayList<>();
+		map = CollStreamUtil.groupByKey(list, Student::getClassId);
+		Assert.assertEquals(map, Collections.EMPTY_MAP);
+		list.add(new Student(1, 1, 1, "张三"));
+		list.add(new Student(1, 2, 2, "李四"));
+		list.add(new Student(2, 1, 1, "擎天柱"));
+		list.add(new Student(2, 2, 2, "威震天"));
+		list.add(new Student(2, 3, 2, "霸天虎"));
+		map = CollStreamUtil.groupByKey(list, Student::getClassId);
+		Map<Long, List<Student>> compare = new HashMap<>();
+		List<Student> class1 = new ArrayList<>();
+		class1.add(new Student(1, 1, 1, "张三"));
+		class1.add(new Student(2, 1, 1, "擎天柱"));
+		compare.put(1L, class1);
+		List<Student> class2 = new ArrayList<>();
+		class2.add(new Student(1, 2, 2, "李四"));
+		class2.add(new Student(2, 2, 2, "威震天"));
+
+		compare.put(2L, class2);
+		List<Student> class3 = new ArrayList<>();
+		class3.add(new Student(2, 3, 2, "霸天虎"));
+		compare.put(3L, class3);
+		Assert.assertEquals(map, compare);
+	}
+
+	public void testGroupBy2Key() {
+		Map<Long, Map<Long, List<Student>>> map = CollStreamUtil.groupBy2Key(null, Student::getTermId, Student::getClassId);
+		Assert.assertEquals(map, Collections.EMPTY_MAP);
+		List<Student> list = new ArrayList<>();
+		map = CollStreamUtil.groupBy2Key(list, Student::getTermId, Student::getClassId);
+		Assert.assertEquals(map, Collections.EMPTY_MAP);
+		list.add(new Student(1, 1, 1, "张三"));
+		list.add(new Student(1, 2, 2, "李四"));
+		list.add(new Student(1, 2, 3, "王五"));
+		list.add(new Student(2, 1, 1, "擎天柱"));
+		list.add(new Student(2, 2, 2, "威震天"));
+		list.add(new Student(2, 2, 3, "霸天虎"));
+		map = CollStreamUtil.groupBy2Key(list, Student::getTermId, Student::getClassId);
+		Map<Long, Map<Long, List<Student>>> compare = new HashMap<>();
+		Map<Long, List<Student>> map1 = new HashMap<>();
+		List<Student> list11 = new ArrayList<>();
+		list11.add(new Student(1, 1, 1, "张三"));
+		map1.put(1L, list11);
+		compare.put(1L, map1);
+		List<Student> list12 = new ArrayList<>();
+		list12.add(new Student(1, 2, 2, "李四"));
+		list12.add(new Student(1, 2, 3, "王五"));
+		map1.put(2L, list12);
+		compare.put(2L, map1);
+		Map<Long, List<Student>> map2 = new HashMap<>();
+		List<Student> list21 = new ArrayList<>();
+		list21.add(new Student(2, 1, 1, "擎天柱"));
+		map2.put(1L, list21);
+		compare.put(2L, map2);
+
+		List<Student> list22 = new ArrayList<>();
+		list22.add(new Student(2, 2, 2, "威震天"));
+		list22.add(new Student(2, 2, 3, "霸天虎"));
+		map2.put(2L, list22);
+		compare.put(2L, map2);
+		Assert.assertEquals(map, compare);
+	}
+
+	@Test
+	public void testGroup2Map() {
+		Map<Long, Map<Long, Student>> map = CollStreamUtil.group2Map(null, Student::getTermId, Student::getClassId);
+		Assert.assertEquals(map, Collections.EMPTY_MAP);
+
+		List<Student> list = new ArrayList<>();
+		map = CollStreamUtil.group2Map(list, Student::getTermId, Student::getClassId);
+		Assert.assertEquals(map, Collections.EMPTY_MAP);
+		list.add(new Student(1, 1, 1, "张三"));
+		list.add(new Student(1, 2, 1, "李四"));
+		list.add(new Student(2, 2, 1, "王五"));
+		map = CollStreamUtil.group2Map(list, Student::getTermId, Student::getClassId);
+		Map<Long, Map<Long, Student>> compare = new HashMap<>();
+		Map<Long, Student> map1 = new HashMap<>();
+		map1.put(1L, new Student(1, 1, 1, "张三"));
+		map1.put(2L, new Student(1, 2, 1, "李四"));
+		compare.put(1L, map1);
+		Map<Long, Student> map2 = new HashMap<>();
+		map2.put(2L, new Student(2, 2, 1, "王五"));
+		compare.put(2L, map2);
+		Assert.assertEquals(compare, map);
+
+	}
+
+	@Test
+	public void testTranslate2List() {
+		List<String> list = CollStreamUtil.toList(null, Student::getName);
+		Assert.assertEquals(list, Collections.EMPTY_LIST);
+		List<Student> students = new ArrayList<>();
+		list = CollStreamUtil.toList(students, Student::getName);
+		Assert.assertEquals(list, Collections.EMPTY_LIST);
+		students.add(new Student(1, 1, 1, "张三"));
+		students.add(new Student(1, 2, 2, "李四"));
+		students.add(new Student(2, 1, 1, "李四"));
+		students.add(new Student(2, 2, 2, "李四"));
+		students.add(new Student(2, 3, 2, "霸天虎"));
+		list = CollStreamUtil.toList(students, Student::getName);
+		List<String> compare = new ArrayList<>();
+		compare.add("张三");
+		compare.add("李四");
+		compare.add("李四");
+		compare.add("李四");
+		compare.add("霸天虎");
+		Assert.assertEquals(list, compare);
+	}
+
+	@Test
+	public void testTranslate2Set() {
+		Set<String> set = CollStreamUtil.toSet(null, Student::getName);
+		Assert.assertEquals(set, Collections.EMPTY_SET);
+		List<Student> students = new ArrayList<>();
+		set = CollStreamUtil.toSet(students, Student::getName);
+		Assert.assertEquals(set, Collections.EMPTY_SET);
+		students.add(new Student(1, 1, 1, "张三"));
+		students.add(new Student(1, 2, 2, "李四"));
+		students.add(new Student(2, 1, 1, "李四"));
+		students.add(new Student(2, 2, 2, "李四"));
+		students.add(new Student(2, 3, 2, "霸天虎"));
+		set = CollStreamUtil.toSet(students, Student::getName);
+		Set<String> compare = new HashSet<>();
+		compare.add("张三");
+		compare.add("李四");
+		compare.add("霸天虎");
+		Assert.assertEquals(set, compare);
+	}
+
+	@Test
+	public void testMerge() {
+		Map<Long, Student> map1 = null;
+		Map<Long, Student> map2 = Collections.emptyMap();
+		Map<Long, String> map = CollStreamUtil.merge(map1, map2, (s1, s2) -> s1.getName() + s2.getName());
+		Assert.assertEquals(map, Collections.EMPTY_MAP);
+		map1 = new HashMap<>();
+		map1.put(1L, new Student(1, 1, 1, "张三"));
+		map = CollStreamUtil.merge(map1, map2, this::merge);
+		Map<Long, String> temp = new HashMap<>();
+		temp.put(1L, "张三");
+		Assert.assertEquals(map, temp);
+		map2 = new HashMap<>();
+		map2.put(1L, new Student(2, 1, 1, "李四"));
+		map = CollStreamUtil.merge(map1, map2, this::merge);
+		Map<Long, String> compare = new HashMap<>();
+		compare.put(1L, "张三李四");
+		Assert.assertEquals(map, compare);
+	}
+
+	private String merge(Student student1, Student student2) {
+		if (student1 == null && student2 == null) {
+			return null;
+		} else if (student1 == null) {
+			return student2.getName();
+		} else if (student2 == null) {
+			return student1.getName();
+		} else {
+			return student1.getName() + student2.getName();
+		}
+	}
+
+	/**
+	 * 班级类
+	 */
+	@Data
+	@AllArgsConstructor
+	@ToString
+	public static class Student {
+		private long termId;//学期id
+		private long classId;//班级id
+		private long studentId;//班级id
+		private String name;//学生名称
+	}
+}

+ 0 - 276
hutool-core/src/test/java/cn/hutool/core/collection/CollectionStreamTest.java

@@ -1,276 +0,0 @@
-package cn.hutool.core.collection;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.util.*;
-
-/**
- * CollectionStream测试方法
- */
-public class CollectionStreamTest {
-    @Test
-    public void testToIdentityMap() {
-        Map<Long, Student> map = CollectionStream.toIdentityMap(null, Student::getStudentId);
-        Assert.assertEquals(map, Collections.EMPTY_MAP);
-        List<Student> list = new ArrayList<>();
-        map = CollectionStream.toIdentityMap(list, Student::getStudentId);
-        Assert.assertEquals(map, Collections.EMPTY_MAP);
-        list.add(new Student(1, 1, 1, "张三"));
-        list.add(new Student(1, 1, 2, "李四"));
-        list.add(new Student(1, 1, 3, "王五"));
-        map = CollectionStream.toIdentityMap(list, Student::getStudentId);
-        Assert.assertEquals(map.get(1L).getName(), "张三");
-        Assert.assertEquals(map.get(2L).getName(), "李四");
-        Assert.assertEquals(map.get(3L).getName(), "王五");
-        Assert.assertEquals(map.get(4L), null);
-    }
-
-    @Test
-    public void testToMap() {
-        Map<Long, String> map = CollectionStream.toMap(null, Student::getStudentId, Student::getName);
-        Assert.assertEquals(map, Collections.EMPTY_MAP);
-        List<Student> list = new ArrayList<>();
-        map = CollectionStream.toMap(list, Student::getStudentId, Student::getName);
-        Assert.assertEquals(map, Collections.EMPTY_MAP);
-        list.add(new Student(1, 1, 1, "张三"));
-        list.add(new Student(1, 1, 2, "李四"));
-        list.add(new Student(1, 1, 3, "王五"));
-        map = CollectionStream.toMap(list, Student::getStudentId, Student::getName);
-        Assert.assertEquals(map.get(1L), "张三");
-        Assert.assertEquals(map.get(2L), "李四");
-        Assert.assertEquals(map.get(3L), "王五");
-        Assert.assertEquals(map.get(4L), null);
-    }
-
-    @Test
-    public void testGroupByKey() {
-        Map<Long, List<Student>> map = CollectionStream.groupByKey(null, Student::getClassId);
-        Assert.assertEquals(map, Collections.EMPTY_MAP);
-        List<Student> list = new ArrayList<>();
-        map = CollectionStream.groupByKey(list, Student::getClassId);
-        Assert.assertEquals(map, Collections.EMPTY_MAP);
-        list.add(new Student(1, 1, 1, "张三"));
-        list.add(new Student(1, 2, 2, "李四"));
-        list.add(new Student(2, 1, 1, "擎天柱"));
-        list.add(new Student(2, 2, 2, "威震天"));
-        list.add(new Student(2, 3, 2, "霸天虎"));
-        map = CollectionStream.groupByKey(list, Student::getClassId);
-        Map<Long, List<Student>> compare = new HashMap<>();
-        List<Student> class1 = new ArrayList<>();
-        class1.add(new Student(1, 1, 1, "张三"));
-        class1.add(new Student(2, 1, 1, "擎天柱"));
-        compare.put(1L, class1);
-        List<Student> class2 = new ArrayList<>();
-        class2.add(new Student(1, 2, 2, "李四"));
-        class2.add(new Student(2, 2, 2, "威震天"));
-
-        compare.put(2L, class2);
-        List<Student> class3 = new ArrayList<>();
-        class3.add(new Student(2, 3, 2, "霸天虎"));
-        compare.put(3L, class3);
-        Assert.assertEquals(true, map.equals(compare));
-    }
-
-    public void testGroupBy2Key() {
-        Map<Long, Map<Long, List<Student>>> map = CollectionStream.groupBy2Key(null, Student::getTermId, Student::getClassId);
-        Assert.assertEquals(map, Collections.EMPTY_MAP);
-        List<Student> list = new ArrayList<>();
-        map = CollectionStream.groupBy2Key(list, Student::getTermId, Student::getClassId);
-        Assert.assertEquals(map, Collections.EMPTY_MAP);
-        list.add(new Student(1, 1, 1, "张三"));
-        list.add(new Student(1, 2, 2, "李四"));
-        list.add(new Student(1, 2, 3, "王五"));
-        list.add(new Student(2, 1, 1, "擎天柱"));
-        list.add(new Student(2, 2, 2, "威震天"));
-        list.add(new Student(2, 2, 3, "霸天虎"));
-        map = CollectionStream.groupBy2Key(list, Student::getTermId, Student::getClassId);
-        Map<Long, Map<Long, List<Student>>> compare = new HashMap<>();
-        Map<Long, List<Student>> map1 = new HashMap<>();
-        List<Student> list11 = new ArrayList<>();
-        list11.add(new Student(1, 1, 1, "张三"));
-        map1.put(1L, list11);
-        compare.put(1L, map1);
-        List<Student> list12 = new ArrayList<>();
-        list12.add(new Student(1, 2, 2, "李四"));
-        list12.add(new Student(1, 2, 3, "王五"));
-        map1.put(2L, list12);
-        compare.put(2L, map1);
-        Map<Long, List<Student>> map2 = new HashMap<>();
-        List<Student> list21 = new ArrayList<>();
-        list21.add(new Student(2, 1, 1, "擎天柱"));
-        map2.put(1L, list21);
-        compare.put(2L, map2);
-
-        List<Student> list22 = new ArrayList<>();
-        list22.add(new Student(2, 2, 2, "威震天"));
-        list22.add(new Student(2, 2, 3, "霸天虎"));
-        map2.put(2L, list22);
-        compare.put(2L, map2);
-        Assert.assertEquals(true, map.equals(compare));
-    }
-
-    @Test
-    public void testGroup2Map() {
-        List<Student> list = null;
-        Map<Long, Map<Long, Student>> map = CollectionStream.group2Map(list, Student::getTermId, Student::getClassId);
-        Assert.assertEquals(map, Collections.EMPTY_MAP);
-        list = new ArrayList<>();
-        map = CollectionStream.group2Map(list, Student::getTermId, Student::getClassId);
-        Assert.assertEquals(map, Collections.EMPTY_MAP);
-        list.add(new Student(1, 1, 1, "张三"));
-        list.add(new Student(1, 2, 1, "李四"));
-        list.add(new Student(2, 2, 1, "王五"));
-        map = CollectionStream.group2Map(list, Student::getTermId, Student::getClassId);
-        Map<Long, Map<Long, Student>> compare = new HashMap<>();
-        Map<Long, Student> map1 = new HashMap<>();
-        map1.put(1L, new Student(1, 1, 1, "张三"));
-        map1.put(2L, new Student(1, 2, 1, "李四"));
-        compare.put(1L, map1);
-        Map<Long, Student> map2 = new HashMap<>();
-        map2.put(2L, new Student(2, 2, 1, "王五"));
-        compare.put(2L, map2);
-        Assert.assertEquals(true, compare.equals(map));
-
-    }
-
-    @Test
-    public void testTranslate2List() {
-        List<String> list = CollectionStream.translate2List(null, Student::getName);
-        Assert.assertEquals(list, Collections.EMPTY_LIST);
-        List<Student> students = new ArrayList<>();
-        list = CollectionStream.translate2List(students, Student::getName);
-        Assert.assertEquals(list, Collections.EMPTY_LIST);
-        students.add(new Student(1, 1, 1, "张三"));
-        students.add(new Student(1, 2, 2, "李四"));
-        students.add(new Student(2, 1, 1, "李四"));
-        students.add(new Student(2, 2, 2, "李四"));
-        students.add(new Student(2, 3, 2, "霸天虎"));
-        list = CollectionStream.translate2List(students, Student::getName);
-        List<String> compare = new ArrayList<>();
-        compare.add("张三");
-        compare.add("李四");
-        compare.add("李四");
-        compare.add("李四");
-        compare.add("霸天虎");
-        Assert.assertEquals(true, list.equals(compare));
-    }
-
-    @Test
-    public void testTranslate2Set() {
-        Set<String> set = CollectionStream.translate2Set(null, Student::getName);
-        Assert.assertEquals(set, Collections.EMPTY_SET);
-        List<Student> students = new ArrayList<>();
-        set = CollectionStream.translate2Set(students, Student::getName);
-        Assert.assertEquals(set, Collections.EMPTY_SET);
-        students.add(new Student(1, 1, 1, "张三"));
-        students.add(new Student(1, 2, 2, "李四"));
-        students.add(new Student(2, 1, 1, "李四"));
-        students.add(new Student(2, 2, 2, "李四"));
-        students.add(new Student(2, 3, 2, "霸天虎"));
-        set = CollectionStream.translate2Set(students, Student::getName);
-        Set<String> compare = new HashSet<>();
-        compare.add("张三");
-        compare.add("李四");
-        compare.add("李四");
-        compare.add("李四");
-        compare.add("霸天虎");
-        Assert.assertEquals(true, set.equals(compare));
-    }
-
-    @Test
-    public void testMerge() {
-        Map<Long, Student> map1 = null;
-        Map<Long, Student> map2 = Collections.EMPTY_MAP;
-        Map<Long, String> map = CollectionStream.merge(map1, map2, (s1, s2) -> s1.getName() + s2.getName());
-        Assert.assertEquals(map, Collections.EMPTY_MAP);
-        map1 = new HashMap<>();
-        map1.put(1L, new Student(1, 1, 1, "张三"));
-        map = CollectionStream.merge(map1, map2, this::merge);
-        Map<Long, String> temp = new HashMap<>();
-        temp.put(1L, "张三");
-        Assert.assertEquals(map, temp);
-        map2 = new HashMap<>();
-        map2.put(1L, new Student(2, 1, 1, "李四"));
-        map = CollectionStream.merge(map1, map2, this::merge);
-        Map<Long, String> compare = new HashMap<>();
-        compare.put(1L, "张三李四");
-        Assert.assertEquals(true, map.equals(compare));
-    }
-
-    public String merge(Student student1, Student student2) {
-        if (student1 == null && student2 == null) {
-            return null;
-        } else if (student1 == null) {
-            return student2.getName();
-        } else if (student2 == null) {
-            return student1.getName();
-        } else {
-            return student1.getName() + student2.getName();
-        }
-    }
-
-    /**
-     * 班级类
-     */
-    public static class Student {
-        private long termId;//学期id
-        private long classId;//班级id
-        private long studentId;//班级id
-        private String name;//学生名称
-
-        public Student(long termId, long classId, long studentId, String name) {
-            this.termId = termId;
-            this.classId = classId;
-            this.studentId = studentId;
-            this.name = name;
-        }
-
-        public long getTermId() {
-            return termId;
-        }
-
-        public void setTermId(long termId) {
-            this.termId = termId;
-        }
-
-        public long getClassId() {
-            return classId;
-        }
-
-        public void setClassId(long classId) {
-            this.classId = classId;
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public void setName(String name) {
-            this.name = name;
-        }
-
-        public long getStudentId() {
-            return studentId;
-        }
-
-        public void setStudentId(long studentId) {
-            this.studentId = studentId;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            return toString().equals(obj.toString());
-        }
-
-        @Override
-        public String toString() {
-            return "Student{" +
-                    "termId=" + termId +
-                    ", classId=" + classId +
-                    ", studentId=" + studentId +
-                    ", name='" + name + '\'' +
-                    '}';
-        }
-    }
-}

+ 14 - 1
hutool-json/src/main/java/cn/hutool/json/JSONUtil.java

@@ -495,10 +495,23 @@ public final class JSONUtil {
 	// -------------------------------------------------------------------- toBean end
 
 	/**
+	 * 将JSONArray字符串转换为Bean的List,默认为ArrayList
+	 *
+	 * @param <T>         Bean类型
+	 * @param jsonArray   JSONArray字符串
+	 * @param elementType List中元素类型
+	 * @return List
+	 * @since 5.5.2
+	 */
+	public static <T> List<T> toList(String jsonArray, Class<T> elementType) {
+		return toList(parseArray(jsonArray), elementType);
+	}
+
+	/**
 	 * 将JSONArray转换为Bean的List,默认为ArrayList
 	 *
 	 * @param <T>         Bean类型
-	 * @param jsonArray   JSONArray
+	 * @param jsonArray   {@link JSONArray}
 	 * @param elementType List中元素类型
 	 * @return List
 	 * @since 4.0.7