!1033 添加解构方法

Merge pull request !1033 from 孔皮皮/v6-dev-List
This commit is contained in:
Looly 2023-07-21 10:18:32 +00:00 committed by Gitee
commit 24361faace
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
4 changed files with 164 additions and 62 deletions

View File

@ -1554,7 +1554,7 @@ public class CollUtil {
// String按照逗号分隔的列表对待
final String arrayStr = StrUtil.unWrap((CharSequence) value, '[', ']');
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
// 如果值为Map而目标为一个Bean则Map应整体转换为Bean而非拆分成Entry转换
iter = new ArrayIter<>(new Object[]{value});
@ -2354,4 +2354,47 @@ public class CollUtil {
}
return collection.stream().allMatch(predicate);
}
/**
* 解构多层集合
* 例如{@code List<List<List<String>>> 解构成 List<String>}
*
* @param collection 需要解构的集合
* @return 解构后的集合
*/
public static <T> List<T> flat(Collection<?> collection) {
return flat(collection, true);
}
/**
* 解构多层集合
* 例如{@code List<List<List<String>>> 解构成 List<String>}
* <p>
* skipNull如果为true, 则解构后的集合里不包含null值为false则会包含null值
*
* @param collection 需要结构的集合
* @param skipNull 是否跳过空的值
* @return 解构后的集合
*/
@SuppressWarnings({"unchecked"})
public static <T> List<T> flat(Collection<?> collection, boolean skipNull) {
LinkedList<Object> queue = new LinkedList<>(collection);
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 (List<T>) result;
}
}

View File

@ -13,6 +13,7 @@
package org.dromara.hutool.core.stream;
import org.dromara.hutool.core.array.ArrayUtil;
import org.dromara.hutool.core.collection.CollUtil;
import org.dromara.hutool.core.collection.ListUtil;
import org.dromara.hutool.core.collection.iter.IterUtil;
import org.dromara.hutool.core.lang.Console;
@ -486,6 +487,17 @@ public interface TransformableWrappedStream<T, S extends TransformableWrappedStr
return wrap(flatMap(recursive).peek(e -> childrenSetter.accept(e, null)));
}
/**
* 如果当前元素是集合则会将集合中的元素解构出来
* 例如{@code List<List<List<String>>> 解构成 List<String>}
*
* @param <R> 函数执行后返回的List里面的类型
* @return EasyStream 一个流
*/
default <R> EasyStream<R> flat() {
return EasyStream.of(CollUtil.flat(nonNull().collect(Collectors.toList())));
}
// endregion
// region ============ map ============

View File

@ -1,5 +1,6 @@
package org.dromara.hutool.core.collection;
import lombok.*;
import org.dromara.hutool.core.collection.iter.IterUtil;
import org.dromara.hutool.core.collection.set.SetUtil;
import org.dromara.hutool.core.comparator.CompareUtil;
@ -7,33 +8,12 @@ import org.dromara.hutool.core.date.DateUtil;
import org.dromara.hutool.core.lang.Console;
import org.dromara.hutool.core.map.Dict;
import org.dromara.hutool.core.map.MapUtil;
import org.dromara.hutool.core.stream.EasyStream;
import org.dromara.hutool.core.text.StrUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Queue;
import java.util.Set;
import java.util.SortedSet;
import java.util.Stack;
import java.util.*;
import java.util.function.Function;
/**
@ -460,9 +440,9 @@ public class CollUtilTest {
@Test
public void sortByPropertyTest() {
final List<TestBean> list = ListUtil.of(
new TestBean("张三", 12, DateUtil.parse("2018-05-01")), //
new TestBean("李四", 13, DateUtil.parse("2018-03-01")), //
new TestBean("王五", 12, DateUtil.parse("2018-04-01"))//
new TestBean("张三", 12, DateUtil.parse("2018-05-01")), //
new TestBean("李四", 13, DateUtil.parse("2018-03-01")), //
new TestBean("王五", 12, DateUtil.parse("2018-04-01"))//
);
CollUtil.sortByProperty(list, "createTime");
@ -474,9 +454,9 @@ public class CollUtilTest {
@Test
public void sortByPropertyTest2() {
final List<TestBean> list = ListUtil.of(
new TestBean("张三", 0, DateUtil.parse("2018-05-01")), //
new TestBean("李四", -12, DateUtil.parse("2018-03-01")), //
new TestBean("王五", 23, DateUtil.parse("2018-04-01"))//
new TestBean("张三", 0, DateUtil.parse("2018-05-01")), //
new TestBean("李四", -12, DateUtil.parse("2018-03-01")), //
new TestBean("王五", 23, DateUtil.parse("2018-04-01"))//
);
CollUtil.sortByProperty(list, "age");
@ -488,8 +468,8 @@ public class CollUtilTest {
@Test
public void fieldValueMapTest() {
final List<TestBean> list = ListUtil.of(new TestBean("张三", 12, DateUtil.parse("2018-05-01")), //
new TestBean("李四", 13, DateUtil.parse("2018-03-01")), //
new TestBean("王五", 12, DateUtil.parse("2018-04-01"))//
new TestBean("李四", 13, DateUtil.parse("2018-03-01")), //
new TestBean("王五", 12, DateUtil.parse("2018-04-01"))//
);
final Map<String, TestBean> map = CollUtil.fieldValueMap(list, "name");
@ -501,8 +481,8 @@ public class CollUtilTest {
@Test
public void fieldValueAsMapTest() {
final List<TestBean> list = ListUtil.of(new TestBean("张三", 12, DateUtil.parse("2018-05-01")), //
new TestBean("李四", 13, DateUtil.parse("2018-03-01")), //
new TestBean("王五", 14, DateUtil.parse("2018-04-01"))//
new TestBean("李四", 13, DateUtil.parse("2018-03-01")), //
new TestBean("王五", 14, DateUtil.parse("2018-04-01"))//
);
final Map<String, Integer> map = CollUtil.fieldValueAsMap(list, "name", "age");
@ -669,7 +649,7 @@ public class CollUtilTest {
@Test
public void subInput1PositiveNegativePositiveOutputArrayIndexOutOfBoundsException() {
Assertions.assertThrows(IndexOutOfBoundsException.class, ()->{
Assertions.assertThrows(IndexOutOfBoundsException.class, () -> {
// Arrange
final List<Integer> list = new ArrayList<>();
list.add(null);
@ -821,8 +801,8 @@ public class CollUtilTest {
oldMap.put("c", "134");
final Map<String, Long> map = IterUtil.toMap(oldMap.entrySet(),
Map.Entry::getKey,
entry -> Long.parseLong(entry.getValue()));
Map.Entry::getKey,
entry -> Long.parseLong(entry.getValue()));
Assertions.assertEquals(1L, (long) map.get("a"));
Assertions.assertEquals(12L, (long) map.get("b"));
@ -900,12 +880,12 @@ public class CollUtilTest {
public void setValueByMapTest() {
// https://gitee.com/dromara/hutool/pulls/482
final List<Person> people = Arrays.asList(
new Person("aa", 12, "man", 1),
new Person("bb", 13, "woman", 2),
new Person("cc", 14, "man", 3),
new Person("dd", 15, "woman", 4),
new Person("ee", 16, "woman", 5),
new Person("ff", 17, "man", 6)
new Person("aa", 12, "man", 1),
new Person("bb", 13, "woman", 2),
new Person("cc", 14, "man", 3),
new Person("dd", 15, "woman", 4),
new Person("ee", 16, "woman", 5),
new Person("ff", 17, "man", 6)
);
final Map<Integer, String> genderMap = new HashMap<>();
@ -946,12 +926,12 @@ public class CollUtilTest {
@Test
public void distinctByFunctionTest() {
final List<Person> people = Arrays.asList(
new Person("aa", 12, "man", 1),
new Person("bb", 13, "woman", 2),
new Person("cc", 14, "man", 3),
new Person("dd", 15, "woman", 4),
new Person("ee", 16, "woman", 5),
new Person("ff", 17, "man", 6)
new Person("aa", 12, "man", 1),
new Person("bb", 13, "woman", 2),
new Person("cc", 14, "man", 3),
new Person("dd", 15, "woman", 4),
new Person("ee", 16, "woman", 5),
new Person("ff", 17, "man", 6)
);
// 覆盖模式下ff覆盖了aaee覆盖了bb
@ -986,10 +966,10 @@ public class CollUtilTest {
@Test
public void mapBeanTest() {
final List<Person> people = Arrays.asList(
new Person("aa", 12, "man", 1),
new Person("bb", 13, "woman", 2),
new Person("cc", 14, "man", 3),
new Person("dd", 15, "woman", 4)
new Person("aa", 12, "man", 1),
new Person("bb", 13, "woman", 2),
new Person("cc", 14, "man", 3),
new Person("dd", 15, "woman", 4)
);
final List<Object> extract = CollUtil.map(people, Person::getName);
@ -1006,10 +986,10 @@ public class CollUtilTest {
@Test
public void transTest() {
final List<Person> people = Arrays.asList(
new Person("aa", 12, "man", 1),
new Person("bb", 13, "woman", 2),
new Person("cc", 14, "man", 3),
new Person("dd", 15, "woman", 4)
new Person("aa", 12, "man", 1),
new Person("bb", 13, "woman", 2),
new Person("cc", 14, "man", 3),
new Person("dd", 15, "woman", 4)
);
final Collection<String> trans = CollUtil.trans(people, Person::getName);
@ -1046,8 +1026,8 @@ public class CollUtilTest {
Assertions.assertNotNull(list);
Assertions.assertEquals(
ListUtil.of(1, 2, 3, 4),
CollUtil.unionAll(ListUtil.of(1), ListUtil.of(2), ListUtil.of(3), ListUtil.of(4))
ListUtil.of(1, 2, 3, 4),
CollUtil.unionAll(ListUtil.of(1), ListUtil.of(2), ListUtil.of(3), ListUtil.of(4))
);
}
@ -1083,14 +1063,14 @@ public class CollUtilTest {
Assertions.assertFalse(CollUtil.addIfAbsent(null, "123"));
Assertions.assertFalse(CollUtil.addIfAbsent(ListUtil.of("123"), "123"));
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(new Animal("jack", 20)),
new Dog("jack", 20)));
new Dog("jack", 20)));
Assertions.assertTrue(CollUtil.addIfAbsent(ListUtil.of(new Animal("jack", 20)),
new Animal("tom", 20)));
new Animal("tom", 20)));
}
@Data
@ -1224,4 +1204,52 @@ public class CollUtilTest {
final List<Pig> pig = Arrays.asList(new Pig("pig1", 12), new Pig("pig2", 12));
Assertions.assertEquals(CollUtil.unionDistinct(dog, cat, pig).size(), 5);
}
@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

@ -708,4 +708,23 @@ public class AbstractEnhancedWrappedStreamTest {
private List<Tree> children;
}
@Test
void test() {
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<String> r = EasyStream.of(list).<String>flat().toList();
Assertions.assertArrayEquals(new String[]{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"}, r.toArray());
}
}