将Java Bean展平为地图
|
我坚持将 Java Bean转换为Map.互联网上有很多资源,但不幸的是,它们都将简单的bean转换为地图.我的那些更广泛. 有简化的例子: public class MyBean {
private String firstName;
private String lastName;
private MyHomeAddress homeAddress;
private int age;
// getters & setters
}
我的观点是生成Map< String,Object>在这种情况下,对于以下条件是正确的: map.containsKey("firstName")
map.containsKey("lastName")
map.containsKey("homeAddress.street") // street is String
map.containsKey("homeAddress.number") // number is int
map.containsKey("homeAddress.city") // city is String
map.containsKey("homeAddress.zipcode") // zipcode is String
map.containsKey("age")
我尝试过使用Apache Commons BeanUtils.两种方法BeanUtils #thedes(Object)和BeanMap(Object)都生成一个“深层次”为1的Map(我的意思是只有“homeAddress”键,将MyHomeAddress对象保存为值).我的方法应该越来越深入地进入对象,直到它遇到基本类型(或字符串),然后它应该停止挖掘和插入键,即“order.customer.contactInfo.home”. 所以,我的问题是:如何轻松完成(或者是否已经存在允许我这样做的项目)? 更新 我已经扩展了Radiodef的答案,还包括Collections,Maps Arrays和Enums: private static boolean isValue(Object value) {
final Class<?> clazz = value.getClass();
if (value == null ||
valueClasses.contains(clazz) ||
Collection.class.isAssignableFrom(clazz) ||
Map.class.isAssignableFrom(clazz) ||
value.getClass().isArray() ||
value.getClass().isEnum()) {
return true;
}
return false;
}
解决方法这是一个简单的反射/递归示例.您应该知道,按照您提出的方式进行转换存在一些问题: >地图键必须是唯一的. 这个例子没有解决这些问题,因为我不确定你想如何解释它们(如果你这样做).如果你的bean继承自Object以外的东西,你需要稍微改变一下你的想法.此示例仅考虑子类的字段. 换句话说,如果你有 public class SubBean extends Bean {
此示例仅返回SubBean中的字段. Java让我们这样做: package com.acme.util;
public class Bean {
private int value;
}
package com.acme.misc;
public class Bean extends com.acme.util.Bean {
private int value;
}
并不是说任何人都应该这样做,但是如果你想使用String作为键是一个问题,因为会有两个名为“value”的键. import java.lang.reflect.*;
import java.util.*;
public final class BeanFlattener {
private BeanFlattener() {}
public static Map<String,Object> deepToMap(Object bean) {
Map<String,Object> map = new LinkedHashMap<>();
try {
putValues(bean,map,null);
} catch (IllegalAccessException x) {
throw new IllegalArgumentException(x);
}
return map;
}
private static void putValues(Object bean,Map<String,Object> map,String prefix)
throws IllegalAccessException {
Class<?> cls = bean.getClass();
for (Field field : cls.getDeclaredFields()) {
if (field.isSynthetic() || Modifier.isStatic(field.getModifiers()))
continue;
field.setAccessible(true);
Object value = field.get(bean);
String key;
if (prefix == null) {
key = field.getName();
} else {
key = prefix + "." + field.getName();
}
if (isValue(value)) {
map.put(key,value);
} else {
putValues(value,key);
}
}
}
private static final Set<Class<?>> VALUE_CLASSES =
Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
Object.class,String.class,Boolean.class,Character.class,Byte.class,Short.class,Integer.class,Long.class,Float.class,Double.class
// etc.
)));
private static boolean isValue(Object value) {
return value == null
|| value instanceof Enum<?>
|| VALUE_CLASSES.contains(value.getClass());
}
} (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- Java泛型:接收实现类的类型参数的接口方法
- 利用3DES实现加密解密的Java代码
- java微信开发API第一步 服务器接入
- 这在Java中 – 线程“main”java.lang.StackOverflowError中
- java – Guava:如何从列表和单个元素创建显式排序?
- Java实现查找当前字符串最大回文串代码分享
- 基于eclipse.ini内存设置的问题详解
- 详解Java中的File文件类以及FileDescriptor文件描述类
- 直接Java / Groovy与ETL工具(Talend / etc) – 您将使用哪些
- java – Hibernate条件使用GROUP BY和RETURN ENTITY LIST
