mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
commit
24361faace
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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 ============
|
||||
|
@ -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覆盖了aa,ee覆盖了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());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user