CollUtil添加解构collection内部的多个collection为单个list的方法

This commit is contained in:
kongweiguang 2023-06-26 13:44:55 +08:00
parent 7cb8492f18
commit 4e047e98e3
4 changed files with 141 additions and 110 deletions

View File

@ -34,6 +34,7 @@ import org.dromara.hutool.core.map.MapUtil;
import org.dromara.hutool.core.reflect.ConstructorUtil; import org.dromara.hutool.core.reflect.ConstructorUtil;
import org.dromara.hutool.core.reflect.FieldUtil; import org.dromara.hutool.core.reflect.FieldUtil;
import org.dromara.hutool.core.reflect.TypeUtil; import org.dromara.hutool.core.reflect.TypeUtil;
import org.dromara.hutool.core.stream.EasyStream;
import org.dromara.hutool.core.stream.StreamUtil; import org.dromara.hutool.core.stream.StreamUtil;
import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.text.split.SplitUtil; import org.dromara.hutool.core.text.split.SplitUtil;
@ -1554,7 +1555,7 @@ public class CollUtil {
// String按照逗号分隔的列表对待 // String按照逗号分隔的列表对待
final String arrayStr = StrUtil.unWrap((CharSequence) value, '[', ']'); final String arrayStr = StrUtil.unWrap((CharSequence) value, '[', ']');
iter = SplitUtil.splitTrim(arrayStr, StrUtil.COMMA).iterator(); iter = SplitUtil.splitTrim(arrayStr, StrUtil.COMMA).iterator();
} else if(value instanceof Map && BeanUtil.isWritableBean(TypeUtil.getClass(elementType))){ } else if (value instanceof Map && BeanUtil.isWritableBean(TypeUtil.getClass(elementType))) {
//https://github.com/dromara/hutool/issues/3139 //https://github.com/dromara/hutool/issues/3139
// 如果值为Map而目标为一个Bean则Map应整体转换为Bean而非拆分成Entry转换 // 如果值为Map而目标为一个Bean则Map应整体转换为Bean而非拆分成Entry转换
iter = new ArrayIter<>(new Object[]{value}); iter = new ArrayIter<>(new Object[]{value});
@ -2354,4 +2355,48 @@ public class CollUtil {
} }
return collection.stream().allMatch(predicate); return collection.stream().allMatch(predicate);
} }
/**
* 结构多层集合
* 例如List<List<List<String>>> 解构成 List<String>
*
* @param collection 需要解构的集合
* @return 解构后的集合
*/
public static List<Object> flat(Collection<?> collection) {
return flat(collection, true);
}
/**
* 结构多层集合
* 例如List<List<List<String>>> 解构成 List<String>
* <p>
* skipNull的作用是当集合里面有个值为空当为true是解构后的集合里面没有null值如果为false则会在解构后的集合里面有努力了
*
* @param collection 需要结构的集合
* @param skipNull 是否跳过空的值
* @return 解构后的集合
*/
@SuppressWarnings({"unchecked"})
public static List<Object> flat(Collection<?> collection, boolean skipNull) {
LinkedList queue = EasyStream.of(collection)
.collect(Collectors.toCollection(LinkedList::new));
List<Object> result = new ArrayList<>();
while (!queue.isEmpty()) {
Object t = queue.removeFirst();
if (skipNull && t == null) {
continue;
}
if (t instanceof Collection) {
queue.addAll((Collection<?>) t);
} else {
result.add(t);
}
}
return result;
}
} }

View File

@ -27,7 +27,6 @@ import org.dromara.hutool.core.util.ObjUtil;
import java.util.*; import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
/** /**
@ -749,46 +748,4 @@ public class ListUtil {
} }
return resList; return resList;
} }
/**
* 解构list里面的list为单个list
*
* @param list 传入的list集合
* @param <T> 返回的元素类型
* @return 解构后的list集合
*/
public static <T> List<T> flatList(List<?> list) {
return flatList(list, Function.identity());
}
/**
* 解构list里面的list并可以对每个元素操作
*
* @param list 传入的list集合
* @param operation 对每个元素进行操作
* @param <T> 返回的元素类型
* @param <O> 最内侧的元素类型
* @return 解构后的list集合
*/
@SuppressWarnings("all")
public static <T, O> List<T> flatList(List<?> list, Function<O, T> operation) {
List<T> result = new ArrayList<>();
if (list == null || list.isEmpty()) {
return result;
}
if (list.get(0) instanceof List) {
for (List<?> subList : (List<List<?>>) list) {
result.addAll(flatList(subList, operation));
}
} else {
for (Object item : list) {
result.add(operation.apply((O) item));
}
}
return result;
}
} }

View File

@ -3,6 +3,7 @@ package org.dromara.hutool.core.collection;
import org.dromara.hutool.core.collection.iter.IterUtil; import org.dromara.hutool.core.collection.iter.IterUtil;
import org.dromara.hutool.core.collection.set.SetUtil; import org.dromara.hutool.core.collection.set.SetUtil;
import org.dromara.hutool.core.comparator.CompareUtil; import org.dromara.hutool.core.comparator.CompareUtil;
import org.dromara.hutool.core.convert.Convert;
import org.dromara.hutool.core.date.DateUtil; import org.dromara.hutool.core.date.DateUtil;
import org.dromara.hutool.core.lang.Console; import org.dromara.hutool.core.lang.Console;
import org.dromara.hutool.core.map.Dict; import org.dromara.hutool.core.map.Dict;
@ -460,9 +461,9 @@ public class CollUtilTest {
@Test @Test
public void sortByPropertyTest() { public void sortByPropertyTest() {
final List<TestBean> list = ListUtil.of( final List<TestBean> list = ListUtil.of(
new TestBean("张三", 12, DateUtil.parse("2018-05-01")), // new TestBean("张三", 12, DateUtil.parse("2018-05-01")), //
new TestBean("李四", 13, DateUtil.parse("2018-03-01")), // new TestBean("李四", 13, DateUtil.parse("2018-03-01")), //
new TestBean("王五", 12, DateUtil.parse("2018-04-01"))// new TestBean("王五", 12, DateUtil.parse("2018-04-01"))//
); );
CollUtil.sortByProperty(list, "createTime"); CollUtil.sortByProperty(list, "createTime");
@ -474,9 +475,9 @@ public class CollUtilTest {
@Test @Test
public void sortByPropertyTest2() { public void sortByPropertyTest2() {
final List<TestBean> list = ListUtil.of( final List<TestBean> list = ListUtil.of(
new TestBean("张三", 0, DateUtil.parse("2018-05-01")), // new TestBean("张三", 0, DateUtil.parse("2018-05-01")), //
new TestBean("李四", -12, DateUtil.parse("2018-03-01")), // new TestBean("李四", -12, DateUtil.parse("2018-03-01")), //
new TestBean("王五", 23, DateUtil.parse("2018-04-01"))// new TestBean("王五", 23, DateUtil.parse("2018-04-01"))//
); );
CollUtil.sortByProperty(list, "age"); CollUtil.sortByProperty(list, "age");
@ -488,8 +489,8 @@ public class CollUtilTest {
@Test @Test
public void fieldValueMapTest() { public void fieldValueMapTest() {
final List<TestBean> list = ListUtil.of(new TestBean("张三", 12, DateUtil.parse("2018-05-01")), // final List<TestBean> list = ListUtil.of(new TestBean("张三", 12, DateUtil.parse("2018-05-01")), //
new TestBean("李四", 13, DateUtil.parse("2018-03-01")), // new TestBean("李四", 13, DateUtil.parse("2018-03-01")), //
new TestBean("王五", 12, DateUtil.parse("2018-04-01"))// new TestBean("王五", 12, DateUtil.parse("2018-04-01"))//
); );
final Map<String, TestBean> map = CollUtil.fieldValueMap(list, "name"); final Map<String, TestBean> map = CollUtil.fieldValueMap(list, "name");
@ -501,8 +502,8 @@ public class CollUtilTest {
@Test @Test
public void fieldValueAsMapTest() { public void fieldValueAsMapTest() {
final List<TestBean> list = ListUtil.of(new TestBean("张三", 12, DateUtil.parse("2018-05-01")), // final List<TestBean> list = ListUtil.of(new TestBean("张三", 12, DateUtil.parse("2018-05-01")), //
new TestBean("李四", 13, DateUtil.parse("2018-03-01")), // new TestBean("李四", 13, DateUtil.parse("2018-03-01")), //
new TestBean("王五", 14, DateUtil.parse("2018-04-01"))// new TestBean("王五", 14, DateUtil.parse("2018-04-01"))//
); );
final Map<String, Integer> map = CollUtil.fieldValueAsMap(list, "name", "age"); final Map<String, Integer> map = CollUtil.fieldValueAsMap(list, "name", "age");
@ -669,7 +670,7 @@ public class CollUtilTest {
@Test @Test
public void subInput1PositiveNegativePositiveOutputArrayIndexOutOfBoundsException() { public void subInput1PositiveNegativePositiveOutputArrayIndexOutOfBoundsException() {
Assertions.assertThrows(IndexOutOfBoundsException.class, ()->{ Assertions.assertThrows(IndexOutOfBoundsException.class, () -> {
// Arrange // Arrange
final List<Integer> list = new ArrayList<>(); final List<Integer> list = new ArrayList<>();
list.add(null); list.add(null);
@ -821,8 +822,8 @@ public class CollUtilTest {
oldMap.put("c", "134"); oldMap.put("c", "134");
final Map<String, Long> map = IterUtil.toMap(oldMap.entrySet(), final Map<String, Long> map = IterUtil.toMap(oldMap.entrySet(),
Map.Entry::getKey, Map.Entry::getKey,
entry -> Long.parseLong(entry.getValue())); entry -> Long.parseLong(entry.getValue()));
Assertions.assertEquals(1L, (long) map.get("a")); Assertions.assertEquals(1L, (long) map.get("a"));
Assertions.assertEquals(12L, (long) map.get("b")); Assertions.assertEquals(12L, (long) map.get("b"));
@ -900,12 +901,12 @@ public class CollUtilTest {
public void setValueByMapTest() { public void setValueByMapTest() {
// https://gitee.com/dromara/hutool/pulls/482 // https://gitee.com/dromara/hutool/pulls/482
final List<Person> people = Arrays.asList( final List<Person> people = Arrays.asList(
new Person("aa", 12, "man", 1), new Person("aa", 12, "man", 1),
new Person("bb", 13, "woman", 2), new Person("bb", 13, "woman", 2),
new Person("cc", 14, "man", 3), new Person("cc", 14, "man", 3),
new Person("dd", 15, "woman", 4), new Person("dd", 15, "woman", 4),
new Person("ee", 16, "woman", 5), new Person("ee", 16, "woman", 5),
new Person("ff", 17, "man", 6) new Person("ff", 17, "man", 6)
); );
final Map<Integer, String> genderMap = new HashMap<>(); final Map<Integer, String> genderMap = new HashMap<>();
@ -946,12 +947,12 @@ public class CollUtilTest {
@Test @Test
public void distinctByFunctionTest() { public void distinctByFunctionTest() {
final List<Person> people = Arrays.asList( final List<Person> people = Arrays.asList(
new Person("aa", 12, "man", 1), new Person("aa", 12, "man", 1),
new Person("bb", 13, "woman", 2), new Person("bb", 13, "woman", 2),
new Person("cc", 14, "man", 3), new Person("cc", 14, "man", 3),
new Person("dd", 15, "woman", 4), new Person("dd", 15, "woman", 4),
new Person("ee", 16, "woman", 5), new Person("ee", 16, "woman", 5),
new Person("ff", 17, "man", 6) new Person("ff", 17, "man", 6)
); );
// 覆盖模式下ff覆盖了aaee覆盖了bb // 覆盖模式下ff覆盖了aaee覆盖了bb
@ -986,10 +987,10 @@ public class CollUtilTest {
@Test @Test
public void mapBeanTest() { public void mapBeanTest() {
final List<Person> people = Arrays.asList( final List<Person> people = Arrays.asList(
new Person("aa", 12, "man", 1), new Person("aa", 12, "man", 1),
new Person("bb", 13, "woman", 2), new Person("bb", 13, "woman", 2),
new Person("cc", 14, "man", 3), new Person("cc", 14, "man", 3),
new Person("dd", 15, "woman", 4) new Person("dd", 15, "woman", 4)
); );
final List<Object> extract = CollUtil.map(people, Person::getName); final List<Object> extract = CollUtil.map(people, Person::getName);
@ -1006,10 +1007,10 @@ public class CollUtilTest {
@Test @Test
public void transTest() { public void transTest() {
final List<Person> people = Arrays.asList( final List<Person> people = Arrays.asList(
new Person("aa", 12, "man", 1), new Person("aa", 12, "man", 1),
new Person("bb", 13, "woman", 2), new Person("bb", 13, "woman", 2),
new Person("cc", 14, "man", 3), new Person("cc", 14, "man", 3),
new Person("dd", 15, "woman", 4) new Person("dd", 15, "woman", 4)
); );
final Collection<String> trans = CollUtil.trans(people, Person::getName); final Collection<String> trans = CollUtil.trans(people, Person::getName);
@ -1046,8 +1047,8 @@ public class CollUtilTest {
Assertions.assertNotNull(list); Assertions.assertNotNull(list);
Assertions.assertEquals( Assertions.assertEquals(
ListUtil.of(1, 2, 3, 4), ListUtil.of(1, 2, 3, 4),
CollUtil.unionAll(ListUtil.of(1), ListUtil.of(2), ListUtil.of(3), ListUtil.of(4)) CollUtil.unionAll(ListUtil.of(1), ListUtil.of(2), ListUtil.of(3), ListUtil.of(4))
); );
} }
@ -1083,14 +1084,14 @@ public class CollUtilTest {
Assertions.assertFalse(CollUtil.addIfAbsent(null, "123")); Assertions.assertFalse(CollUtil.addIfAbsent(null, "123"));
Assertions.assertFalse(CollUtil.addIfAbsent(ListUtil.of("123"), "123")); Assertions.assertFalse(CollUtil.addIfAbsent(ListUtil.of("123"), "123"));
Assertions.assertFalse(CollUtil.addIfAbsent(ListUtil.of(new Animal("jack", 20)), Assertions.assertFalse(CollUtil.addIfAbsent(ListUtil.of(new Animal("jack", 20)),
new Animal("jack", 20))); new Animal("jack", 20)));
// 正常情况 // 正常情况
Assertions.assertTrue(CollUtil.addIfAbsent(ListUtil.of("456"), "123")); Assertions.assertTrue(CollUtil.addIfAbsent(ListUtil.of("456"), "123"));
Assertions.assertTrue(CollUtil.addIfAbsent(ListUtil.of(new Animal("jack", 20)), Assertions.assertTrue(CollUtil.addIfAbsent(ListUtil.of(new Animal("jack", 20)),
new Dog("jack", 20))); new Dog("jack", 20)));
Assertions.assertTrue(CollUtil.addIfAbsent(ListUtil.of(new Animal("jack", 20)), Assertions.assertTrue(CollUtil.addIfAbsent(ListUtil.of(new Animal("jack", 20)),
new Animal("tom", 20))); new Animal("tom", 20)));
} }
@Data @Data
@ -1181,4 +1182,51 @@ public class CollUtilTest {
public void minNullTest() { public void minNullTest() {
Assertions.assertNull(CollUtil.max(null)); Assertions.assertNull(CollUtil.max(null));
} }
@Test
public void flatListTest1() {
List<List<List<String>>> list = Arrays.asList(Arrays.asList(Arrays.asList("1", "2", "3"), Arrays.asList("5", "6", "7")));
List<Object> objects = CollUtil.flat(list);
Assertions.assertArrayEquals(new String[]{"1", "2", "3", "5", "6", "7"}, objects.toArray());
}
@Test
public void flatListTest2() {
List<List<List<String>>> list = Arrays.asList(
Arrays.asList(
Arrays.asList("a"),
Arrays.asList("b", "c"),
Arrays.asList("d", "e", "f")
),
Arrays.asList(
Arrays.asList("g", "h", "i"),
Arrays.asList("j", "k", "l")
)
);
List<Object> flat = CollUtil.flat(list);
Assertions.assertArrayEquals(new String[]{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"}, flat.toArray());
}
@Test
void flatListTest3() {
List<List<List<String>>> list = Arrays.asList(
Arrays.asList(
Arrays.asList("a"),
Arrays.asList("b", "c", null),
Arrays.asList("d", "e", "f")
),
Arrays.asList(
Arrays.asList("g", "h", "i"),
Arrays.asList("j", "k", "l")
)
);
List<Object> flat = CollUtil.flat(list, false);
Assertions.assertArrayEquals(new String[]{"a", "b", "c", null, "d", "e", "f", "g", "h", "i", "j", "k", "l"}, flat.toArray());
}
} }

View File

@ -2,7 +2,6 @@ package org.dromara.hutool.core.collection;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import org.dromara.hutool.core.convert.Convert;
import org.dromara.hutool.core.date.StopWatch; import org.dromara.hutool.core.date.StopWatch;
import org.dromara.hutool.core.lang.Console; import org.dromara.hutool.core.lang.Console;
import org.dromara.hutool.core.lang.page.PageInfo; import org.dromara.hutool.core.lang.page.PageInfo;
@ -79,7 +78,7 @@ public class ListUtilTest {
@Test @Test
public void splitAvgNotZero() { public void splitAvgNotZero() {
Assertions.assertThrows(IllegalArgumentException.class, () -> { Assertions.assertThrows(IllegalArgumentException.class, ()->{
// limit不能小于等于0 // limit不能小于等于0
ListUtil.avgPartition(Arrays.asList(1, 2, 3, 4), 0); ListUtil.avgPartition(Arrays.asList(1, 2, 3, 4), 0);
}); });
@ -123,7 +122,7 @@ public class ListUtilTest {
public void pageTest2() { public void pageTest2() {
final List<Integer> a = ListUtil.ofLinked(1, 2, 3, 4, 5); final List<Integer> a = ListUtil.ofLinked(1, 2, 3, 4, 5);
final int[] d1 = ListUtil.page(a, PageInfo.of(a.size(), 8).setFirstPageNo(0).setPageNo(0)) final int[] d1 = ListUtil.page(a, PageInfo.of(a.size(), 8).setFirstPageNo(0).setPageNo(0))
.stream().mapToInt(Integer::valueOf).toArray(); .stream().mapToInt(Integer::valueOf).toArray();
Assertions.assertArrayEquals(new int[]{1, 2, 3, 4, 5}, d1); Assertions.assertArrayEquals(new int[]{1, 2, 3, 4, 5}, d1);
} }
@ -171,11 +170,11 @@ public class ListUtilTest {
} }
final List<TestBean> beanList = ListUtil.of( final List<TestBean> beanList = ListUtil.of(
new TestBean(2, "test2"), new TestBean(2, "test2"),
new TestBean(1, "test1"), new TestBean(1, "test1"),
new TestBean(5, "test5"), new TestBean(5, "test5"),
new TestBean(4, "test4"), new TestBean(4, "test4"),
new TestBean(3, "test3") new TestBean(3, "test3")
); );
final List<TestBean> order = ListUtil.sortByProperty(beanList, "order"); final List<TestBean> order = ListUtil.sortByProperty(beanList, "order");
@ -246,13 +245,13 @@ public class ListUtilTest {
} }
@Test @Test
public void ofCopyOnWriteTest() { public void ofCopyOnWriteTest(){
final CopyOnWriteArrayList<String> strings = ListUtil.ofCopyOnWrite(ListUtil.of("a", "b")); final CopyOnWriteArrayList<String> strings = ListUtil.ofCopyOnWrite(ListUtil.of("a", "b"));
Assertions.assertEquals(2, strings.size()); Assertions.assertEquals(2, strings.size());
} }
@Test @Test
public void ofCopyOnWriteTest2() { public void ofCopyOnWriteTest2(){
final CopyOnWriteArrayList<String> strings = ListUtil.ofCopyOnWrite("a", "b"); final CopyOnWriteArrayList<String> strings = ListUtil.ofCopyOnWrite("a", "b");
Assertions.assertEquals(2, strings.size()); Assertions.assertEquals(2, strings.size());
} }
@ -270,22 +269,4 @@ public class ListUtilTest {
ListUtil.reverseNew(list); ListUtil.reverseNew(list);
} }
@Test
public void flatListTest1() {
List<List<List<String>>> list = Arrays.asList(Arrays.asList(Arrays.asList("1", "2", "3"), Arrays.asList("5", "6", "7")));
List<String> objects = ListUtil.flatList(list);
Assertions.assertArrayEquals(new String[]{"1", "2", "3", "5", "6", "7"}, objects.toArray());
}
@Test
public void flatListTest2() {
List<List<List<String>>> list = Arrays.asList(Arrays.asList(Arrays.asList("1", "2", "3"), Arrays.asList("5", "6", "7")));
List<Integer> objects = ListUtil.flatList(list, Convert::toInt);
Assertions.assertArrayEquals(new Integer[]{1, 2, 3, 5, 6, 7}, objects.toArray());
}
} }