add toBean support Map

This commit is contained in:
Looly 2020-05-25 11:36:20 +08:00
parent b9e468d6c7
commit 9ff2d650bb
6 changed files with 79 additions and 36 deletions

View File

@ -3,7 +3,7 @@
-------------------------------------------------------------------------------------------------------------
## 5.3.6 (2020-05-19)
## 5.3.6 (2020-05-25)
### 新特性
* 【core 】 NumberConverter Long类型增加日期转换pr#872@Github
@ -14,6 +14,7 @@
* 【core 】 ImgUtil增加toBase64DateUriURLUtil增加getDataUri方法
* 【core 】 IterUtil添加List转Map的工具方法pr#123@Gitee
* 【core 】 BeanValuePovider转换失败时返回原数据而非null
* 【core 】 支持BeanUtil.toBean(object, Map.class)转换issue#I1I4HC@Gitee
### Bug修复
* 【core 】 修复SimpleCache死锁问题issue#I1HOKB@Gitee

View File

@ -476,7 +476,7 @@ public class BeanUtil {
* @since 5.2.4
*/
public static <T> T toBean(Object source, Class<T> clazz, CopyOptions options) {
final T target = ReflectUtil.newInstance(clazz);
final T target = ReflectUtil.newInstanceIfPossible(clazz);
copyProperties(source, target, options);
return target;
}

View File

@ -13,6 +13,7 @@ import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@ -769,13 +770,32 @@ public class ReflectUtil {
/**
* 尝试遍历并调用此类的所有构造方法直到构造成功并返回
* <p>
* 对于某些特殊的接口按照其默认实现实例化例如
* <pre>
* Map - HashMap
* Collction - ArrayList
* List - ArrayList
* Set - HashSet
* </pre>
*
* @param <T> 对象类型
* @param beanClass 被构造的类
* @return 构造后的对象
*/
@SuppressWarnings("unchecked")
public static <T> T newInstanceIfPossible(Class<T> beanClass) {
Assert.notNull(beanClass);
// 某些特殊接口的实例化按照默认实现进行
if (beanClass.isAssignableFrom(AbstractMap.class)) {
beanClass = (Class<T>) HashMap.class;
} else if (beanClass.isAssignableFrom(List.class)) {
beanClass = (Class<T>) ArrayList.class;
} else if (beanClass.isAssignableFrom(Set.class)) {
beanClass = (Class<T>) HashSet.class;
}
try {
return newInstance(beanClass);
} catch (Exception e) {

View File

@ -1741,14 +1741,14 @@ public class StrUtil {
* 如果分隔字符串为空串""则返回空串如果分隔字符串未找到返回原字符串举例如下
*
* <pre>
* StrUtil.subBefore(null, *) = null
* StrUtil.subBefore("", *) = ""
* StrUtil.subBefore("abc", "a") = ""
* StrUtil.subBefore("abcba", "b") = "a"
* StrUtil.subBefore("abc", "c") = "ab"
* StrUtil.subBefore("abc", "d") = "abc"
* StrUtil.subBefore("abc", "") = ""
* StrUtil.subBefore("abc", null) = "abc"
* StrUtil.subBefore(null, *, false) = null
* StrUtil.subBefore("", *, false) = ""
* StrUtil.subBefore("abc", "a", false) = ""
* StrUtil.subBefore("abcba", "b", false) = "a"
* StrUtil.subBefore("abc", "c", false) = "ab"
* StrUtil.subBefore("abc", "d", false) = "abc"
* StrUtil.subBefore("abc", "", false) = ""
* StrUtil.subBefore("abc", null, false) = "abc"
* </pre>
*
* @param string 被查找的字符串
@ -1783,12 +1783,12 @@ public class StrUtil {
* 如果分隔字符串未找到返回原字符串举例如下
*
* <pre>
* StrUtil.subBefore(null, *) = null
* StrUtil.subBefore("", *) = ""
* StrUtil.subBefore("abc", 'a') = ""
* StrUtil.subBefore("abcba", 'b') = "a"
* StrUtil.subBefore("abc", 'c') = "ab"
* StrUtil.subBefore("abc", 'd') = "abc"
* StrUtil.subBefore(null, *, false) = null
* StrUtil.subBefore("", *, false) = ""
* StrUtil.subBefore("abc", 'a', false) = ""
* StrUtil.subBefore("abcba", 'b', false) = "a"
* StrUtil.subBefore("abc", 'c', false) = "ab"
* StrUtil.subBefore("abc", 'd', false) = "abc"
* </pre>
*
* @param string 被查找的字符串
@ -1819,14 +1819,14 @@ public class StrUtil {
* 如果分隔字符串为空串null或""则返回空串如果分隔字符串未找到返回空串举例如下
*
* <pre>
* StrUtil.subAfter(null, *) = null
* StrUtil.subAfter("", *) = ""
* StrUtil.subAfter(*, null) = ""
* StrUtil.subAfter("abc", "a") = "bc"
* StrUtil.subAfter("abcba", "b") = "cba"
* StrUtil.subAfter("abc", "c") = ""
* StrUtil.subAfter("abc", "d") = ""
* StrUtil.subAfter("abc", "") = "abc"
* StrUtil.subAfter(null, *, false) = null
* StrUtil.subAfter("", *, false) = ""
* StrUtil.subAfter(*, null, false) = ""
* StrUtil.subAfter("abc", "a", false) = "bc"
* StrUtil.subAfter("abcba", "b", false) = "cba"
* StrUtil.subAfter("abc", "c", false) = ""
* StrUtil.subAfter("abc", "d", false) = ""
* StrUtil.subAfter("abc", "", false) = "abc"
* </pre>
*
* @param string 被查找的字符串
@ -1857,12 +1857,12 @@ public class StrUtil {
* 如果分隔字符串为空串null或""则返回空串如果分隔字符串未找到返回空串举例如下
*
* <pre>
* StrUtil.subAfter(null, *) = null
* StrUtil.subAfter("", *) = ""
* StrUtil.subAfter("abc", 'a') = "bc"
* StrUtil.subAfter("abcba", 'b') = "cba"
* StrUtil.subAfter("abc", 'c') = ""
* StrUtil.subAfter("abc", 'd') = ""
* StrUtil.subAfter(null, *, false) = null
* StrUtil.subAfter("", *, false) = ""
* StrUtil.subAfter("abc", 'a', false) = "bc"
* StrUtil.subAfter("abcba", 'b', false) = "cba"
* StrUtil.subAfter("abc", 'c', false) = ""
* StrUtil.subAfter("abc", 'd', false) = ""
* </pre>
*
* @param string 被查找的字符串

View File

@ -75,6 +75,22 @@ public class BeanUtilTest {
Assert.assertEquals(person.getOpenid(), "DFDFSDFWERWER");
}
@Test
public void toBeanTest(){
SubPerson person = new SubPerson();
person.setAge(14);
person.setOpenid("11213232");
person.setName("测试A11");
person.setSubName("sub名字");
final Map<?, ?> map = BeanUtil.toBean(person, Map.class);
Assert.assertEquals("测试A11", map.get("name"));
Assert.assertEquals(14, map.get("age"));
Assert.assertEquals("11213232", map.get("openid"));
// static属性应被忽略
Assert.assertFalse(map.containsKey("SUBNAME"));
}
@Test
public void mapToBeanIgnoreCaseTest() {
HashMap<String, Object> map = CollUtil.newHashMap();

View File

@ -1,15 +1,15 @@
package cn.hutool.core.convert;
import cn.hutool.core.bean.BeanUtilTest.SubPerson;
import cn.hutool.core.lang.Console;
import cn.hutool.core.lang.TypeReference;
import org.junit.Assert;
import org.junit.Test;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import cn.hutool.core.lang.Console;
import org.junit.Assert;
import org.junit.Test;
import cn.hutool.core.bean.BeanUtilTest.SubPerson;
/**
* 类型转换工具单元测试<br>
* 转换为数组
@ -45,6 +45,12 @@ public class ConvertToBeanTest {
Assert.assertEquals("测试A11", map.get("name"));
Assert.assertEquals("14", map.get("age"));
Assert.assertEquals("11213232", map.get("openid"));
final LinkedHashMap<String, String> map2 = Convert.convert(
new TypeReference<LinkedHashMap<String, String>>() {}, person);
Assert.assertEquals("测试A11", map2.get("name"));
Assert.assertEquals("14", map2.get("age"));
Assert.assertEquals("11213232", map2.get("openid"));
}
@Test