mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
Merge branch 'v6-dev' of gitee.com:dromara/hutool into v6-dev
This commit is contained in:
commit
a24cf8d3d0
@ -1554,7 +1554,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 +2354,49 @@ public class CollUtil {
|
|||||||
}
|
}
|
||||||
return collection.stream().allMatch(predicate);
|
return collection.stream().allMatch(predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解构多层集合
|
||||||
|
* 例如:{@code List<List<List<String>>> 解构成 List<String>}
|
||||||
|
*
|
||||||
|
* @param <T> 元素类型
|
||||||
|
* @param collection 需要解构的集合
|
||||||
|
* @return 解构后的集合
|
||||||
|
*/
|
||||||
|
public static <T> List<T> flat(final Collection<?> collection) {
|
||||||
|
return flat(collection, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解构多层集合
|
||||||
|
* 例如:{@code List<List<List<String>>> 解构成 List<String>}
|
||||||
|
* <p>
|
||||||
|
* skipNull如果为true, 则解构后的集合里不包含null值,为false则会包含null值。
|
||||||
|
*
|
||||||
|
* @param <T> 元素类型
|
||||||
|
* @param collection 需要结构的集合
|
||||||
|
* @param skipNull 是否跳过空的值
|
||||||
|
* @return 解构后的集合
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"unchecked"})
|
||||||
|
public static <T> List<T> flat(final Collection<?> collection, final boolean skipNull) {
|
||||||
|
final LinkedList<Object> queue = new LinkedList<>(collection);
|
||||||
|
|
||||||
|
final List<Object> result = new ArrayList<>();
|
||||||
|
|
||||||
|
while (isNotEmpty(queue)) {
|
||||||
|
final 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,9 @@
|
|||||||
|
|
||||||
package org.dromara.hutool.core.comparator;
|
package org.dromara.hutool.core.comparator;
|
||||||
|
|
||||||
|
import org.dromara.hutool.core.convert.Convert;
|
||||||
|
import org.dromara.hutool.core.regex.PatternPool;
|
||||||
|
import org.dromara.hutool.core.regex.ReUtil;
|
||||||
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;
|
||||||
import org.dromara.hutool.core.util.ObjUtil;
|
import org.dromara.hutool.core.util.ObjUtil;
|
||||||
@ -87,6 +90,15 @@ public class VersionComparator implements Comparator<String>, Serializable {
|
|||||||
diff = v1.length() - v2.length();
|
diff = v1.length() - v2.length();
|
||||||
if (0 == diff) {
|
if (0 == diff) {
|
||||||
diff = v1.compareTo(v2);
|
diff = v1.compareTo(v2);
|
||||||
|
}else {
|
||||||
|
// https://gitee.com/dromara/hutool/pulls/1043
|
||||||
|
//不同长度的先比较前面的数字;前面数字不相等时,按数字大小比较;数字相等的时候,继续按长度比较,
|
||||||
|
final int v1Num = Convert.toInt(ReUtil.get(PatternPool.NUMBERS, v1, 0), 0);
|
||||||
|
final int v2Num = Convert.toInt(ReUtil.get(PatternPool.NUMBERS, v2, 0), 0);
|
||||||
|
final int diff1 = v1Num - v2Num;
|
||||||
|
if (diff1 != 0) {
|
||||||
|
diff = diff1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(diff != 0) {
|
if(diff != 0) {
|
||||||
//已有结果,结束
|
//已有结果,结束
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
package org.dromara.hutool.core.stream;
|
package org.dromara.hutool.core.stream;
|
||||||
|
|
||||||
import org.dromara.hutool.core.array.ArrayUtil;
|
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.ListUtil;
|
||||||
import org.dromara.hutool.core.collection.iter.IterUtil;
|
import org.dromara.hutool.core.collection.iter.IterUtil;
|
||||||
import org.dromara.hutool.core.lang.Console;
|
import org.dromara.hutool.core.lang.Console;
|
||||||
@ -486,6 +487,18 @@ public interface TransformableWrappedStream<T, S extends TransformableWrappedStr
|
|||||||
return wrap(flatMap(recursive).peek(e -> childrenSetter.accept(e, null)));
|
return wrap(flatMap(recursive).peek(e -> childrenSetter.accept(e, null)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果当前元素是集合,则会将集合中的元素解构出来
|
||||||
|
* 例如:{@code List<List<List<String>>> 解构成 List<String>}
|
||||||
|
*
|
||||||
|
* @param <R> 函数执行后返回的List里面的类型
|
||||||
|
* @return EasyStream 一个流
|
||||||
|
* @since 6.0.0
|
||||||
|
*/
|
||||||
|
default <R> EasyStream<R> flat() {
|
||||||
|
return EasyStream.of(CollUtil.flat(nonNull().collect(Collectors.toList())));
|
||||||
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region ============ map ============
|
// region ============ map ============
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package org.dromara.hutool.core.collection;
|
package org.dromara.hutool.core.collection;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
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;
|
||||||
@ -8,32 +9,10 @@ import org.dromara.hutool.core.lang.Console;
|
|||||||
import org.dromara.hutool.core.map.Dict;
|
import org.dromara.hutool.core.map.Dict;
|
||||||
import org.dromara.hutool.core.map.MapUtil;
|
import org.dromara.hutool.core.map.MapUtil;
|
||||||
import org.dromara.hutool.core.text.StrUtil;
|
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.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.ArrayDeque;
|
import java.util.*;
|
||||||
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.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -460,9 +439,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 +453,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 +467,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 +480,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 +648,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 +800,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 +879,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 +925,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覆盖了aa,ee覆盖了bb
|
// 覆盖模式下ff覆盖了aa,ee覆盖了bb
|
||||||
@ -986,10 +965,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 +985,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 +1025,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 +1062,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
|
||||||
@ -1224,4 +1203,55 @@ public class CollUtilTest {
|
|||||||
final List<Pig> pig = Arrays.asList(new Pig("pig1", 12), new Pig("pig2", 12));
|
final List<Pig> pig = Arrays.asList(new Pig("pig1", 12), new Pig("pig2", 12));
|
||||||
Assertions.assertEquals(CollUtil.unionDistinct(dog, cat, pig).size(), 5);
|
Assertions.assertEquals(CollUtil.unionDistinct(dog, cat, pig).size(), 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("ArraysAsListWithZeroOrOneArgument")
|
||||||
|
@Test
|
||||||
|
public void flatListTest1() {
|
||||||
|
final List<List<List<String>>> list = Arrays.asList(Arrays.asList(Arrays.asList("1", "2", "3"), Arrays.asList("5", "6", "7")));
|
||||||
|
|
||||||
|
final List<Object> objects = CollUtil.flat(list);
|
||||||
|
|
||||||
|
Assertions.assertArrayEquals(new String[]{"1", "2", "3", "5", "6", "7"}, objects.toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("ArraysAsListWithZeroOrOneArgument")
|
||||||
|
@Test
|
||||||
|
public void flatListTest2() {
|
||||||
|
final 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")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
final List<Object> flat = CollUtil.flat(list);
|
||||||
|
Assertions.assertArrayEquals(new String[]{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"}, flat.toArray());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("ArraysAsListWithZeroOrOneArgument")
|
||||||
|
@Test
|
||||||
|
void flatListTest3() {
|
||||||
|
final 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")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
final 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());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -53,4 +53,10 @@ public class VersionComparatorTest {
|
|||||||
final VersionComparator other = new VersionComparator();
|
final VersionComparator other = new VersionComparator();
|
||||||
Assertions.assertNotEquals(first, other);
|
Assertions.assertNotEquals(first, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void versionComparatorTest7() {
|
||||||
|
final int compare = VersionComparator.INSTANCE.compare("1.12.2", "1.12.1c");
|
||||||
|
Assertions.assertTrue(compare > 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -708,4 +708,23 @@ public class AbstractEnhancedWrappedStreamTest {
|
|||||||
private List<Tree> children;
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,6 @@ import org.dromara.hutool.setting.Setting;
|
|||||||
* @author Luxiaolei
|
* @author Luxiaolei
|
||||||
*/
|
*/
|
||||||
public final class DbUtil {
|
public final class DbUtil {
|
||||||
private final static Log log = Log.get();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从配置文件中读取SQL打印选项,读取后会去除相应属性
|
* 从配置文件中读取SQL打印选项,读取后会去除相应属性
|
||||||
@ -34,25 +33,24 @@ public final class DbUtil {
|
|||||||
*/
|
*/
|
||||||
public static void setShowSqlGlobal(final Setting setting) {
|
public static void setShowSqlGlobal(final Setting setting) {
|
||||||
// 初始化SQL显示
|
// 初始化SQL显示
|
||||||
final boolean isShowSql = Convert.toBoolean(setting.remove(DSKeys.KEY_SHOW_SQL), false);
|
final boolean isShowSql = Convert.toBoolean(setting.remove(DSKeys.KEY_SHOW_SQL));
|
||||||
final boolean isFormatSql = Convert.toBoolean(setting.remove(DSKeys.KEY_FORMAT_SQL), false);
|
final boolean isFormatSql = Convert.toBoolean(setting.remove(DSKeys.KEY_FORMAT_SQL));
|
||||||
final boolean isShowParams = Convert.toBoolean(setting.remove(DSKeys.KEY_SHOW_PARAMS), false);
|
final boolean isShowParams = Convert.toBoolean(setting.remove(DSKeys.KEY_SHOW_PARAMS));
|
||||||
String sqlLevelStr = setting.remove(DSKeys.KEY_SQL_LEVEL);
|
String sqlLevelStr = setting.remove(DSKeys.KEY_SQL_LEVEL);
|
||||||
if (null != sqlLevelStr) {
|
if (null != sqlLevelStr) {
|
||||||
sqlLevelStr = sqlLevelStr.toUpperCase();
|
sqlLevelStr = sqlLevelStr.toUpperCase();
|
||||||
}
|
}
|
||||||
final Level level = Convert.toEnum(Level.class, sqlLevelStr, Level.DEBUG);
|
final Level level = Convert.toEnum(Level.class, sqlLevelStr);
|
||||||
log.debug("Show sql: [{}], format sql: [{}], show params: [{}], level: [{}]", isShowSql, isFormatSql, isShowParams, level);
|
|
||||||
setShowSqlGlobal(isShowSql, isFormatSql, isShowParams, level);
|
setShowSqlGlobal(isShowSql, isFormatSql, isShowParams, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置全局配置:是否通过debug日志显示SQL
|
* 设置全局配置:是否通过debug日志显示SQL
|
||||||
*
|
*
|
||||||
* @param isShowSql 是否显示SQL
|
* @param isShowSql 是否显示SQL,{@code null}表示保持默认
|
||||||
* @param isFormatSql 是否格式化显示的SQL
|
* @param isFormatSql 是否格式化显示的SQL,{@code null}表示保持默认
|
||||||
* @param isShowParams 是否打印参数
|
* @param isShowParams 是否打印参数,{@code null}表示保持默认
|
||||||
* @param level SQL打印到的日志等级
|
* @param level 日志级别,{@code null}表示保持默认
|
||||||
* @see GlobalDbConfig#setShowSql(boolean, boolean, boolean, Level)
|
* @see GlobalDbConfig#setShowSql(boolean, boolean, boolean, Level)
|
||||||
* @since 4.1.7
|
* @since 4.1.7
|
||||||
*/
|
*/
|
||||||
|
@ -112,10 +112,10 @@ public class GlobalDbConfig {
|
|||||||
/**
|
/**
|
||||||
* 设置全局配置:是否通过debug日志显示SQL
|
* 设置全局配置:是否通过debug日志显示SQL
|
||||||
*
|
*
|
||||||
* @param isShowSql 是否显示SQL
|
* @param isShowSql 是否显示SQL,{@code null}表示保持默认
|
||||||
* @param isFormatSql 是否格式化显示的SQL
|
* @param isFormatSql 是否格式化显示的SQL,{@code null}表示保持默认
|
||||||
* @param isShowParams 是否打印参数
|
* @param isShowParams 是否打印参数,{@code null}表示保持默认
|
||||||
* @param level SQL打印到的日志等级
|
* @param level 日志级别,{@code null}表示保持默认
|
||||||
*/
|
*/
|
||||||
public static void setShowSql(final boolean isShowSql, final boolean isFormatSql, final boolean isShowParams, final Level level) {
|
public static void setShowSql(final boolean isShowSql, final boolean isFormatSql, final boolean isShowParams, final Level level) {
|
||||||
SqlLog.INSTANCE.init(isShowSql, isFormatSql, isShowParams, level);
|
SqlLog.INSTANCE.init(isShowSql, isFormatSql, isShowParams, level);
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
package org.dromara.hutool.db.sql;
|
package org.dromara.hutool.db.sql;
|
||||||
|
|
||||||
|
import org.dromara.hutool.core.collection.CollUtil;
|
||||||
import org.dromara.hutool.core.collection.ListUtil;
|
import org.dromara.hutool.core.collection.ListUtil;
|
||||||
import org.dromara.hutool.core.array.ArrayUtil;
|
import org.dromara.hutool.core.array.ArrayUtil;
|
||||||
import org.dromara.hutool.db.DbRuntimeException;
|
import org.dromara.hutool.db.DbRuntimeException;
|
||||||
@ -19,6 +20,7 @@ import org.dromara.hutool.db.Entity;
|
|||||||
import org.dromara.hutool.db.Page;
|
import org.dromara.hutool.db.Page;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询对象,用于传递查询所需的字段值<br>
|
* 查询对象,用于传递查询所需的字段值<br>
|
||||||
@ -26,30 +28,45 @@ import java.util.Collection;
|
|||||||
* 如果想自定义返回结果,则可在查询对象中自定义要查询的字段名,分页{@link Page}信息来自定义结果。
|
* 如果想自定义返回结果,则可在查询对象中自定义要查询的字段名,分页{@link Page}信息来自定义结果。
|
||||||
*
|
*
|
||||||
* @author Looly
|
* @author Looly
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class Query implements Cloneable {
|
public class Query implements Cloneable {
|
||||||
|
|
||||||
/** 查询的字段名列表 */
|
/**
|
||||||
|
* 查询的字段名列表
|
||||||
|
*/
|
||||||
Collection<String> fields;
|
Collection<String> fields;
|
||||||
/** 查询的表名 */
|
/**
|
||||||
|
* 查询的表名
|
||||||
|
*/
|
||||||
String[] tableNames;
|
String[] tableNames;
|
||||||
/** 查询的条件语句 */
|
/**
|
||||||
|
* 查询的条件语句
|
||||||
|
*/
|
||||||
Condition[] where;
|
Condition[] where;
|
||||||
/** 分页对象 */
|
/**
|
||||||
|
* 分页对象
|
||||||
|
*/
|
||||||
Page page;
|
Page page;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从{@link Entity}构建Query
|
* 从{@link Entity}构建Query
|
||||||
|
*
|
||||||
* @param where 条件查询{@link Entity},包含条件Map和表名
|
* @param where 条件查询{@link Entity},包含条件Map和表名
|
||||||
* @return Query
|
* @return Query
|
||||||
* @since 5.5.3
|
* @since 5.5.3
|
||||||
*/
|
*/
|
||||||
public static Query of(final Entity where){
|
public static Query of(final Entity where) {
|
||||||
return new Query(SqlUtil.buildConditions(where), where.getTableName());
|
final Query query = new Query(SqlUtil.buildConditions(where), where.getTableName());
|
||||||
|
final Set<String> fieldNames = where.getFieldNames();
|
||||||
|
if (CollUtil.isNotEmpty(fieldNames)) {
|
||||||
|
query.setFields(fieldNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------- Constructor start
|
// --------------------------------------------------------------- Constructor start
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
*
|
*
|
||||||
@ -63,7 +80,7 @@ public class Query implements Cloneable {
|
|||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
*
|
*
|
||||||
* @param where 条件语句
|
* @param where 条件语句
|
||||||
* @param tableNames 表名
|
* @param tableNames 表名
|
||||||
*/
|
*/
|
||||||
public Query(final Condition[] where, final String... tableNames) {
|
public Query(final Condition[] where, final String... tableNames) {
|
||||||
@ -73,8 +90,8 @@ public class Query implements Cloneable {
|
|||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
*
|
*
|
||||||
* @param where 条件语句
|
* @param where 条件语句
|
||||||
* @param page 分页
|
* @param page 分页
|
||||||
* @param tableNames 表名
|
* @param tableNames 表名
|
||||||
*/
|
*/
|
||||||
public Query(final Condition[] where, final Page page, final String... tableNames) {
|
public Query(final Condition[] where, final Page page, final String... tableNames) {
|
||||||
@ -84,10 +101,10 @@ public class Query implements Cloneable {
|
|||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
*
|
*
|
||||||
* @param fields 字段
|
* @param fields 字段
|
||||||
* @param tableNames 表名
|
* @param tableNames 表名
|
||||||
* @param where 条件
|
* @param where 条件
|
||||||
* @param page 分页
|
* @param page 分页
|
||||||
*/
|
*/
|
||||||
public Query(final Collection<String> fields, final String[] tableNames, final Condition[] where, final Page page) {
|
public Query(final Collection<String> fields, final String[] tableNames, final Condition[] where, final Page page) {
|
||||||
this.fields = fields;
|
this.fields = fields;
|
||||||
@ -98,6 +115,7 @@ public class Query implements Cloneable {
|
|||||||
// --------------------------------------------------------------- Constructor end
|
// --------------------------------------------------------------- Constructor end
|
||||||
|
|
||||||
// --------------------------------------------------------------- Getters and Setters start
|
// --------------------------------------------------------------- Getters and Setters start
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得查询的字段名列表
|
* 获得查询的字段名列表
|
||||||
*
|
*
|
||||||
@ -206,7 +224,7 @@ public class Query implements Cloneable {
|
|||||||
@Override
|
@Override
|
||||||
public Query clone() {
|
public Query clone() {
|
||||||
try {
|
try {
|
||||||
return (Query) super.clone();
|
return (Query) super.clone();
|
||||||
} catch (final CloneNotSupportedException e) {
|
} catch (final CloneNotSupportedException e) {
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
}
|
}
|
||||||
|
@ -50,16 +50,26 @@ public class SqlLog {
|
|||||||
/**
|
/**
|
||||||
* 设置全局配置:是否通过debug日志显示SQL
|
* 设置全局配置:是否通过debug日志显示SQL
|
||||||
*
|
*
|
||||||
* @param isShowSql 是否显示SQL
|
* @param isShowSql 是否显示SQL,{@code null}表示保持默认
|
||||||
* @param isFormatSql 是否格式化显示的SQL
|
* @param isFormatSql 是否格式化显示的SQL,{@code null}表示保持默认
|
||||||
* @param isShowParams 是否打印参数
|
* @param isShowParams 是否打印参数,{@code null}表示保持默认
|
||||||
* @param level 日志级别
|
* @param level 日志级别,{@code null}表示保持默认
|
||||||
*/
|
*/
|
||||||
public void init(final boolean isShowSql, final boolean isFormatSql, final boolean isShowParams, final Level level) {
|
public void init(final Boolean isShowSql, final Boolean isFormatSql, final Boolean isShowParams, final Level level) {
|
||||||
this.showSql = isShowSql;
|
if (null != isShowSql) {
|
||||||
this.formatSql = isFormatSql;
|
this.showSql = isShowSql;
|
||||||
this.showParams = isShowParams;
|
}
|
||||||
this.level = level;
|
if (null != isFormatSql) {
|
||||||
|
this.formatSql = isFormatSql;
|
||||||
|
}
|
||||||
|
if (null != isShowParams) {
|
||||||
|
this.showParams = isShowParams;
|
||||||
|
}
|
||||||
|
if (null != level) {
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
log.debug("Show sql: [{}], format sql: [{}], show params: [{}], level: [{}]",
|
||||||
|
this.showSql, this.formatSql, this.showParams, this.level);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,7 +41,7 @@ public class UserInfo implements Serializable{
|
|||||||
// JDK1.4 {@code user.country},JDK1.2 {@code user.region}
|
// JDK1.4 {@code user.country},JDK1.2 {@code user.region}
|
||||||
String userCountry = SystemUtil.get("user.country", false);
|
String userCountry = SystemUtil.get("user.country", false);
|
||||||
if(null == userCountry){
|
if(null == userCountry){
|
||||||
userCountry = SystemUtil.get("user.country", false);
|
userCountry = SystemUtil.get("user.region", false);
|
||||||
}
|
}
|
||||||
USER_COUNTRY = userCountry;
|
USER_COUNTRY = userCountry;
|
||||||
}
|
}
|
||||||
|
64
hutool-json/src/test/java/org/dromara/hutool/json/IssueI7M2GZTest.java
Executable file
64
hutool-json/src/test/java/org/dromara/hutool/json/IssueI7M2GZTest.java
Executable file
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||||
|
* Hutool is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.dromara.hutool.json;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.dromara.hutool.core.reflect.TypeReference;
|
||||||
|
import org.dromara.hutool.json.serialize.JSONDeserializer;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://gitee.com/dromara/hutool/issues/I7M2GZ
|
||||||
|
*/
|
||||||
|
public class IssueI7M2GZTest {
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class JSONBeanParserImpl implements JSONDeserializer<JSONBeanParserImpl> {
|
||||||
|
private String name;
|
||||||
|
private Integer parsed;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONBeanParserImpl deserialize(final JSON json) {
|
||||||
|
setName("new Object");
|
||||||
|
setParsed(12);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class MyEntity<T> {
|
||||||
|
private List<T> list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void toListTest() {
|
||||||
|
final List<JSONBeanParserImpl> list = new ArrayList<>();
|
||||||
|
list.add(new JSONBeanParserImpl("Object1", 1));
|
||||||
|
|
||||||
|
final MyEntity<JSONBeanParserImpl> entity = new MyEntity<>();
|
||||||
|
entity.setList(list);
|
||||||
|
|
||||||
|
final String json = JSONUtil.toJsonStr(entity);
|
||||||
|
//Console.log(json);
|
||||||
|
final MyEntity<JSONBeanParserImpl> result = JSONUtil.toBean(json, new TypeReference<MyEntity<JSONBeanParserImpl>>() {});
|
||||||
|
Assertions.assertEquals("new Object", result.getList().get(0).getName());
|
||||||
|
Assertions.assertNotNull(result.getList().get(0).getParsed());
|
||||||
|
Assertions.assertEquals(Integer.valueOf(12), result.getList().get(0).getParsed());
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user