Skip to content

Instantly share code, notes, and snippets.

@pfmiles
Created January 6, 2017 07:30
Show Gist options
  • Save pfmiles/cd6945785f1a7f07ea6678750ffd1cc1 to your computer and use it in GitHub Desktop.
Save pfmiles/cd6945785f1a7f07ea6678750ffd1cc1 to your computer and use it in GitHub Desktop.
使用from对象,update指定对象(to, 符合javaBean规范的pojo)
package test;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author pf-miles Dec 14, 2016 3:59:00 PM
*/
public class BeanUtil {
private static final String DATE_FMT_SIMPLE = "yyyy-MM-dd";
private static final String DATE_FMT_NORMAL = "yyyy-MM-dd HH:mm:ss";
private static final String DATE_FMT_FULL = "yyyy-MM-dd HH:mm:ssZ";
// 'tryCreatePojoInstance'方法使用的,构造函数的缓存(可能是NULL对象)
private static final ConcurrentHashMap<Class<?>, Object> tryCreateInstConsCache = new ConcurrentHashMap<Class<?>, Object>(
16, 0.75f, BumonitorSdkConstants.CLIENT_CPU_NUM * 10);
// getter方法缓存: [cls, propName] -> method or NULL
private static final ConcurrentHashMap<Pair<Class<?>, String>, Object> readerCache = new ConcurrentHashMap<Pair<Class<?>, String>, Object>(
16, 0.75f, BumonitorSdkConstants.CLIENT_CPU_NUM * 10);
// setter方法缓存: [cls, propName] -> method or NULL
private static final ConcurrentHashMap<Pair<Class<?>, String>, Object> writerCache = new ConcurrentHashMap<Pair<Class<?>, String>, Object>(
16, 0.75f, BumonitorSdkConstants.CLIENT_CPU_NUM * 10);
/**
* 使用from对象,update指定对象(to, 符合javaBean规范的pojo);遵循javaBean规范映射(setter方法),若有任何属性缺失或名称不匹配则忽略; 但一旦属性名匹配上,就一定保证update成功,否则抛错;<br/>
* 当然也支持map、collection的update;<br/>
* 当from为null时,不做任何动作;<br/>
* 当to为null时,新建to同类型的对象,之后正常映射;<br/>
* 对于容器内部元素仅支持update, 不支持add, 即:被映射的目标不能为null
*
* @param from map作为数据来源方
* @param toRef 将要被update的目标对象的ref
*/
@SuppressWarnings("unchecked")
public static <T> void update(Object from, Ref<T> toRef,
Class<?> toCls) throws BumonitorSdkException {
// 若from是null则不用做任何事情
if (from == null)
return;
// 若目标是基本类型及其wrapper类型或String、java.util.Date,则采用直接替换策略
if (ClassUtil.isPrimitiveOrWrapper(toCls) || String.class.equals(toCls)
|| java.util.Date.class.equals(toCls)) {
toRef.setTarget((T) castToBaseTypes(from, toCls));
return;
}
// 若target已排除是基本类型,且是null,则创建一个
if (toRef.getTarget() == null)
toRef.setTarget((T) tryCreatePojoInstance(toCls));
// 执行update策略
if (Map.class.isAssignableFrom(toCls)) {
// update map
if (!(from instanceof Map))
throw new BumonitorSdkException("Cannot update map using a non-map object, type: "
+ from.getClass().getName() + ".");
Map<Object, Object> toMap = (Map<Object, Object>) toRef.getTarget();
Map<Object, Object> fromMap = (Map<Object, Object>) from;
for (Map.Entry<Object, Object> fromEntry : fromMap.entrySet()) {
// 遍历fromMap以确定本次处理希望update toMap的哪些字段
Object fv = fromEntry.getValue();
if (fv != null) {
Object k = fromEntry.getKey();
if (toMap.containsKey(k)) {
Object tv = toMap.get(k);
if (tv != null) {// 对于容器内部元素仅支持update, 不支持add
Ref<Object> tr = new Ref<Object>(tv);
update(fv, tr, tv.getClass());
toMap.put(k, tr.getTarget());
}
}
}
}
} else if (Collection.class.isAssignableFrom(toCls)) {
// update collection
if (!(from instanceof Collection))
throw new BumonitorSdkException(
"Cannot update collection using a non-collection object, type: "
+ from.getClass().getName() + ".");
if (List.class.isAssignableFrom(toCls)) {
// listIterator处理方式
List<Object> toCol = (List<Object>) toRef.getTarget();
Collection<Object> fromCol = (Collection<Object>) from;
// zipped遍历,fromCol对应位置元素若不为null, 则进行更新
ListIterator<Object> toIter = toCol.listIterator();
Iterator<Object> fromIter = fromCol.iterator();
while (fromIter.hasNext() && toIter.hasNext()) {
Object fromObj = fromIter.next();
Object toObj = toIter.next();
if (fromObj != null && toObj != null) {// 仅支持update, 不支持add
Ref<Object> tr = new Ref<Object>(toObj);
update(fromObj, tr, toObj.getClass());
toIter.set(tr.getTarget());
}
}
} else {
// create new方式
Collection<Object> newTo = (Collection<Object>) tryCreatePojoInstance(toCls);
Collection<Object> toCol = (Collection<Object>) toRef.getTarget();
Collection<Object> fromCol = (Collection<Object>) from;
// zipped遍历,fromCol对应位置元素若不为null, 则进行更新,否则直接加入newTo; 最后需替换ref内的对象到newTo
Iterator<Object> toIter = toCol.iterator();
Iterator<Object> fromIter = fromCol.iterator();
while (toIter.hasNext()) {
Object tv = toIter.next();
if (fromIter.hasNext()) {
Object fv = fromIter.next();
if (fv != null && tv != null) {
Ref<Object> tr = new Ref<Object>(tv);
update(fv, tr, tv.getClass());
tv = tr.getTarget();
}
}
newTo.add(tv);
}
toRef.setTarget((T) newTo);
}
} else if (toCls.isArray()) {
// update array
if (!(from instanceof Collection))
throw new BumonitorSdkException(
"Cannot update array using a non-collection object, type: "
+ from.getClass().getName() + ".");
T to = toRef.getTarget();
Iterator<Object> fromIter = ((Collection<Object>) from).iterator();
int arrSize = Array.getLength(to);
for (int i = 0; i < arrSize && fromIter.hasNext(); i++) {
Object fv = fromIter.next();
if (fv != null) {
Object tv = Array.get(to, i);
Class<?> itype = null;
if (tv != null) {
itype = tv.getClass();
} else {
Class<?> ctype = toCls.getComponentType();
if (!ctype.isInterface() && !Modifier.isAbstract(ctype.getModifiers()))
itype = ctype;
}
if (itype != null) {
Ref<Object> tr = new Ref<Object>(tv);
update(fv, tr, itype);
Array.set(to, i, tr.getTarget());
}
}
}
} else {
// update pojo
if (!(from instanceof Map))
throw new BumonitorSdkException("Cannot update pojo using a non-map object, type: "
+ from.getClass().getName() + ".");
T to = toRef.getTarget();
Map<Object, Object> fromMap = (Map<Object, Object>) from;
for (Map.Entry<Object, Object> fromEntry : fromMap.entrySet()) {
// 遍历fromMap以确定本次处理希望update toMap的哪些字段
Object fv = fromEntry.getValue();
if (fv != null) {
String k = String.valueOf(fromEntry.getKey());
if (hasProperty(to, k)) {
Object tv = getProperty(to, k);
Class<?> itype = null;
if (tv != null) {
itype = tv.getClass();
} else {
Class<?> ptype = getPropertyRetType(to, k);
if (ptype != null && !ptype.isInterface()
&& !Modifier.isAbstract(ptype.getModifiers()))
itype = ptype;
}
if (itype != null) {
Ref<Object> tr = new Ref<Object>(tv);
update(fv, tr, itype);
setProperty(to, k, tr.getTarget());
}
}
}
}
}
}
private static Class<?> getPropertyRetType(Object obj, String propName) {
Object v = resolveReader(obj, propName);
if (Null.NULL.equals(v)) {
return null;
} else {
return ((Method) v).getReturnType();
}
}
private static void setProperty(Object obj, String propName, Object value) {
Class<?> cls = obj.getClass();
Pair<Class<?>, String> k = new Pair<Class<?>, String>(cls, propName);
Object v = writerCache.get(k);
if (v == null) {
// load v
BeanInfo bi = null;
try {
bi = Introspector.getBeanInfo(cls);
} catch (IntrospectionException e) {
SdkConfig.LOGGER.error("Error when introspecting class: " + cls.getName() + ".", e);
}
if (bi != null)
for (PropertyDescriptor pd : bi.getPropertyDescriptors()) {
String pname = pd.getName();
if ("class".equals(pname))// 忽略'getClass'
continue;
if (propName.equals(pname)) {
Method w = pd.getWriteMethod();
if (w != null) {
w.setAccessible(true);
v = w;
}
}
}
if (v == null)
v = Null.NULL;
writerCache.put(k, v);
}
if (Null.NULL.equals(v)) {
SdkConfig.LOGGER.error("No writer method found when writing property: " + propName
+ ", obj: " + String.valueOf(obj) + ".");
} else {
try {
((Method) v).invoke(obj, value);
} catch (Exception e) {
SdkConfig.LOGGER
.error("Error when setting property: " + propName + ", obj: "
+ String.valueOf(obj) + ", val: " + String.valueOf(value) + ".",
e);
}
}
}
private static Object getProperty(Object obj, String propName) {
Object v = resolveReader(obj, propName);
if (Null.NULL.equals(v)) {
SdkConfig.LOGGER.error("No reader method found when reading property: " + propName
+ ", obj: " + String.valueOf(obj) + ".");
return null;
} else {
try {
return ((Method) v).invoke(obj);
} catch (Exception e) {
SdkConfig.LOGGER.error("Error when getting property: " + propName + ", obj: "
+ String.valueOf(obj) + ".",
e);
return null;
}
}
}
/**
* 对象身上是否存在指定名称的属性
*/
private static boolean hasProperty(Object obj, String propName) {
Object v = resolveReader(obj, propName);
return !Null.NULL.equals(v);
}
private static Object resolveReader(Object obj, String propName) {
Class<?> cls = obj.getClass();
Pair<Class<?>, String> k = new Pair<Class<?>, String>(cls, propName);
Object v = readerCache.get(k);
if (v == null) {
// load v
BeanInfo bi = null;
try {
bi = Introspector.getBeanInfo(cls);
} catch (IntrospectionException e) {
SdkConfig.LOGGER.error("Error when introspecting class: " + cls.getName() + ".", e);
}
if (bi != null)
for (PropertyDescriptor pd : bi.getPropertyDescriptors()) {
String pname = pd.getName();
if ("class".equals(pname))// 忽略'getClass'
continue;
if (propName.equals(pname)) {
Method r = pd.getReadMethod();
if (r != null) {
r.setAccessible(true);
v = r;
}
}
}
if (v == null)
v = Null.NULL;
readerCache.put(k, v);
}
return v;
}
/**
* 尝试创建指定javaBean类的新对象,本方法会依次尝试无参构造函数,然后参数由少到多的其它构造函数; 若没有任何public的构造函数或调用构造函数失败则抛错;方法本身带有可用构造函数cache
* @param cls 想要创建实例的类
* @return 创建好的实例对象, 若有构造函数参数则全部为null
*/
@SuppressWarnings("unchecked")
public static <T> T tryCreatePojoInstance(Class<T> cls) throws BumonitorSdkException {
try {
Object c = tryCreateInstConsCache.get(cls);
if (c == null) {
// 尝试找到参数最少的那个public构造函数,并放入缓存
if (cls.isInterface() || Modifier.isAbstract(cls.getModifiers()))
throw new BumonitorSdkException(
"Cannot create instance of a interface or abstract class, class name: "
+ cls.getName() + ".");
Constructor<?>[] cs = cls.getConstructors();
if (cs == null | cs.length == 0) {
c = Null.NULL;
} else {
for (Constructor<?> i : cs)
if (c == null
|| ((c instanceof Constructor)
&& consParamCount(i) < consParamCount((Constructor<?>) c)))
c = i;
if (c != null) {
((Constructor<?>) c).setAccessible(true);// boost reflection
} else {
c = Null.NULL;
}
}
tryCreateInstConsCache.put(cls, c);
}
if (Null.NULL.equals(c)) {
throw new BumonitorSdkException("No public constructor found for class: "
+ cls.getName() + ", try create instance failed.");
} else {
Constructor<?> cc = (Constructor<?>) c;
return (T) cc.newInstance(new Object[consParamCount(cc)]);
}
} catch (Exception e) {
if (e instanceof BumonitorSdkException)
throw (BumonitorSdkException) e;
else
throw new BumonitorSdkException(
"Error when trying to create instance of class: " + String.valueOf(cls) + ".",
e);
}
}
private static int consParamCount(Constructor<?> c) {
return c.getParameterTypes().length;
}
/**
* 将指定对象转换成指定类型的对象返回,该方法只针对基本类型及其包装类型,以及String、Date、Boolean、Character
*/
@SuppressWarnings("unchecked")
public static <T> T castToBaseTypes(Object obj,
Class<T> targetType) throws BumonitorSdkException {
try {
if (obj == null)
return null;
if (targetType.isInstance(obj))
return (T) obj;
if (String.class.equals(targetType))
return (T) String.valueOf(obj);
if (java.util.Date.class.equals(targetType))
return (T) parseDate(String.valueOf(obj));
if (Boolean.class.equals(targetType) || boolean.class.equals(targetType))
return (T) (Boolean) Boolean.parseBoolean(String.valueOf(obj));
if (Character.class.equals(targetType) || char.class.equals(targetType))
if (obj instanceof Number) {
return (T) Character.valueOf((char) ((Number) obj).intValue());
} else {
return (T) Character.valueOf(String.valueOf(obj).charAt(0));
}
if (Number.class.isAssignableFrom(targetType)) {
if (Number.class.isInstance(obj)) {
return convertNumber((Number) obj, targetType);
} else if (String.class.isInstance(obj)) {
return convertNumber(Double.parseDouble((String) obj), targetType);
}
}
return (T) obj;
} catch (Exception e) {
if (e instanceof BumonitorSdkException)
throw (BumonitorSdkException) e;
else
throw new BumonitorSdkException(e);
}
}
@SuppressWarnings("unchecked")
private static <T> T convertNumber(Number n, Class<T> targetType) {
if (Byte.class.equals(targetType) || byte.class.equals(targetType))
return (T) (Byte) n.byteValue();
if (Short.class.equals(targetType) || short.class.equals(targetType))
return (T) (Short) n.shortValue();
if (Integer.class.equals(targetType) || int.class.equals(targetType))
return (T) (Integer) n.intValue();
if (Long.class.equals(targetType) || long.class.equals(targetType))
return (T) (Long) n.longValue();
if (Double.class.equals(targetType) || double.class.equals(targetType))
return (T) (Double) n.doubleValue();
if (Float.class.equals(targetType) || float.class.equals(targetType))
return (T) (Float) n.floatValue();
if (BigDecimal.class.equals(targetType))
return (T) BigDecimal.valueOf(n.doubleValue());
if (BigInteger.class.equals(targetType))
return (T) BigInteger.valueOf(n.longValue());
return (T) n;
}
/**
* 将string按照默认的三种格式转换成java.util.Date对象
* @throws BumonitorSdkException
*/
public static Date parseDate(String dateStr) throws BumonitorSdkException {
if (dateStr == null)
return null;
int len = dateStr.length();
try {
if (DATE_FMT_NORMAL.length() == len) {
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FMT_NORMAL);
return sdf.parse(dateStr);
} else if (DATE_FMT_SIMPLE.length() == len) {
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FMT_SIMPLE);
return sdf.parse(dateStr);
} else if (DATE_FMT_NORMAL.length() + 5 == len) {
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FMT_FULL);
return sdf.parse(dateStr);
} else {
throw new ParseException("Unrecognized date format: " + dateStr + ".", 0);
}
} catch (ParseException e) {
throw new BumonitorSdkException(e);
}
}
}
package test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.junit.Assert;
import org.junit.Test;
/**
* @author pf-miles Dec 15, 2016 4:51:59 PM
*/
public class BeanUtilTest {
public static final class Pojo {
private String name;
private int age;
private Pojo2 p2;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Pojo2 getP2() {
return p2;
}
public void setP2(Pojo2 p2) {
this.p2 = p2;
}
}
// 2参构造函数pojo
public static final class Pojo2 {
private String name;
private String gender;
public Pojo2(String p1, String p2) {
this.name = p1;
this.gender = p2;
}
public Pojo2(String p) {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
// 私有构造函数pojo
public static final class PriPojo {
private PriPojo() {
}
}
@SuppressWarnings("unchecked")
@Test
public void testTryCreatePojoInstance() throws BumonitorSdkException {
// pojo, 构造函数参数...
Pojo p = BeanUtil.tryCreatePojoInstance(Pojo.class);
Assert.assertTrue(p != null);
Pojo2 p2 = BeanUtil.tryCreatePojoInstance(Pojo2.class);
Assert.assertTrue(p2 != null);
// map/set/list
Map<String, Object> m = BeanUtil.tryCreatePojoInstance(HashMap.class);
Assert.assertTrue(m != null);
Set<String> s = BeanUtil.tryCreatePojoInstance(HashSet.class);
Assert.assertTrue(s != null);
List<String> l = BeanUtil.tryCreatePojoInstance(ArrayList.class);
Assert.assertTrue(l != null);
// 抛错情形
try {
BeanUtil.tryCreatePojoInstance(PriPojo.class);
Assert.fail();
} catch (BumonitorSdkException e) {
Assert.assertTrue(true);
}
}
@Test
public void testUpdate() throws BumonitorSdkException {
// 基本类型
Ref<Integer> toRef = new Ref<Integer>(1);
BeanUtil.update(5, toRef, Integer.class);
Assert.assertTrue(new Integer(5).equals(toRef.getTarget()));
BeanUtil.update(7.5, toRef, Integer.class);
Assert.assertTrue(new Integer(7).equals(toRef.getTarget()));
BeanUtil.update("13", toRef, Integer.class);
Assert.assertTrue(new Integer(13).equals(toRef.getTarget()));
// pojo类型
Pojo p = new Pojo();
p.setName("wenyue");
p.setAge(30);
Ref<Pojo> pojoRef = new Ref<Pojo>(p);
Map<String, Object> fromMap = new HashMap<String, Object>();
fromMap.put("name", "weiwei");
fromMap.put("age", 32);
BeanUtil.update(fromMap, pojoRef, Pojo.class);
Assert.assertTrue("weiwei".equals(p.getName()));
Assert.assertTrue(32 == p.getAge());
fromMap.put("name", "xingyan");
fromMap.put("age", 3);
BeanUtil.update(fromMap, pojoRef, Pojo.class);
Assert.assertTrue("xingyan".equals(p.getName()));
Assert.assertTrue(3 == p.getAge());
Pojo2 p2 = new Pojo2("lihong", "female");
p.setP2(p2);
fromMap.clear();
Map<String, Object> p2Map = new HashMap<String, Object>();
p2Map.put("name", "fuping");
p2Map.put("gender", "male");
fromMap.put("p2", p2Map);
BeanUtil.update(fromMap, pojoRef, Pojo.class);
Assert.assertTrue("fuping".equals(p.getP2().getName()));
Assert.assertTrue("male".equals(p.getP2().getGender()));
p2Map.put("name", "min");
p2Map.put("gender", "female");
BeanUtil.update(fromMap, pojoRef, Pojo.class);
Assert.assertTrue("min".equals(p.getP2().getName()));
Assert.assertTrue("female".equals(p.getP2().getGender()));
// map
fromMap.clear();
Map<Object, Object> m = new HashMap<Object, Object>();
m.put("name", "wenyue");
m.put("age", 30);
Ref<Map<Object, Object>> mapRef = new Ref<Map<Object, Object>>(m);
fromMap.put("name", "weiwei");
fromMap.put("age", 32);
BeanUtil.update(fromMap, mapRef, HashMap.class);
Assert.assertTrue("weiwei".equals(m.get("name")));
Assert.assertTrue(new Integer(32).equals(m.get("age")));
Map<Object, Object> m2 = new HashMap<Object, Object>();
m2.put("name", "lihong");
m2.put("age", 52);
m.put("m2", m2);
fromMap.clear();
Map<String, Object> m2From = new HashMap<String, Object>();
m2From.put("name", "xingyan");
m2From.put("age", 3);
fromMap.put("m2", m2From);
BeanUtil.update(fromMap, mapRef, HashMap.class);
Assert.assertTrue("xingyan".equals(m2.get("name")));
Assert.assertTrue(new Integer(3).equals(m2.get("age")));
// collection, 分'in-place'更新形式和'create new'更新形式
List<Object> inPlaceCol = new ArrayList<Object>();
Map<String, Object> mi = new HashMap<String, Object>();
mi.put("mapName", "mapName1");
mi.put("mapAge", 10);
inPlaceCol.add(mi);
inPlaceCol.add(null);
Pojo pi = new Pojo();
pi.setName("pojo1");
pi.setAge(11);
Pojo2 pi2 = new Pojo2("pojo2", "male");
pi.setP2(pi2);
inPlaceCol.add(pi);
Ref<Collection<Object>> inPlaceRef = new Ref<Collection<Object>>(inPlaceCol);
List<Map<String, Object>> fromCol = new ArrayList<Map<String, Object>>();
Map<String, Object> fromMap1 = new HashMap<String, Object>();
fromMap1.put("mapName", "wenyue");
fromMap1.put("mapAge", 30);
fromCol.add(fromMap1);
fromCol.add(null);
Map<String, Object> fromMap2 = new HashMap<String, Object>();
fromMap2.put("name", "weiwei");
fromMap2.put("age", 32);
p2Map.clear();
p2Map.put("name", "xingyan");
p2Map.put("gender", "female");
fromMap2.put("p2", p2Map);
fromCol.add(fromMap2);
BeanUtil.update(fromCol, inPlaceRef, ArrayList.class);
Assert.assertTrue(mi.get("mapName").equals("wenyue"));
Assert.assertTrue(mi.get("mapAge").equals(30));
Assert.assertTrue(pi.getName().equals("weiwei"));
Assert.assertTrue(pi.getAge() == 32);
Assert.assertTrue(pi2.getName().equals("xingyan"));
Assert.assertTrue(pi2.getGender().equals("female"));
// array
Object[] arr = new Object[3];
arr[0] = mi;
arr[1] = null;
arr[2] = pi;
fromMap1.put("mapName", "huimo");
fromMap1.put("mapAge", 27);
fromMap2.put("name", "chanmu");
fromMap2.put("age", 32);
p2Map.put("name", "yunchuan");
p2Map.put("gender", "male");
Ref<Object[]> arrRef = new Ref<Object[]>(arr);
BeanUtil.update(fromCol, arrRef, Object[].class);
Assert.assertTrue(mi.get("mapName").equals("huimo"));
Assert.assertTrue(mi.get("mapAge").equals(27));
Assert.assertTrue(pi.getName().equals("chanmu"));
Assert.assertTrue(pi.getAge() == 32);
Assert.assertTrue(pi2.getName().equals("yunchuan"));
Assert.assertTrue(pi2.getGender().equals("male"));
// create new形式的col
Set<Object> createNewCol = new LinkedHashSet<Object>();
createNewCol.add(mi);
createNewCol.add(pi);
fromMap1.put("mapName", "aaa");
fromMap1.put("mapAge", 1111);
fromMap2.put("name", "bbb");
fromMap2.put("age", 2222);
p2Map.put("name", "ccc");
p2Map.put("gender", "dddd");
Ref<Collection<?>> createNewColRef = new Ref<Collection<?>>(createNewCol);
fromCol.clear();
fromCol.add(fromMap1);
fromCol.add(fromMap2);
BeanUtil.update(fromCol, createNewColRef, LinkedHashSet.class);
Assert.assertTrue(mi.get("mapName").equals("aaa"));
Assert.assertTrue(mi.get("mapAge").equals(1111));
Assert.assertTrue(pi.getName().equals("bbb"));
Assert.assertTrue(pi.getAge() == 2222);
Assert.assertTrue(pi2.getName().equals("ccc"));
Assert.assertTrue(pi2.getGender().equals("dddd"));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment