我正在寻找一种最简单的方法来对平面Map进行深层复制< String,String>对bean的嵌套属性一些嵌套属性是我想为其提供实例化策略的接口。例如:
Map<String, String> customer = new Map<String, String>();
customers.put("id", "123");
customers.put("address.line1", "221B Baker St.");
public class Customer {
private int id;
private Address address; //address is an interface
... getters/setters ...
}
请注意,我不想提供显式映射,只是为接口提供具体实例的策略。我假设commons-beanutils这样做,但它们是功能的开放JIRA票证。具有类似功能的库是Google GSON,它提供了一个名为InstanceCreator的接口。
我已经在beanutils之上实现了一个解决方案,但是有一个内置了这个功能的bean转换库吗?
答案 0 :(得分:0)
你有点表达两种不同的东西。更容易做的事情就是你最初描述的东西,深度嵌套的字符串映射。所以
put("id", "1") -> map.put("id", "1")
put("address.line1", "221b") -> ((Map)map.get("address")).put("221B")
(我为了简洁而忽略了实际的安全检查是那里的地图,如果是这样的话,yadda yadda,所有这些都让我们喜欢java简洁的做事方式。)
然后把“a.b.c.d ...”递归地向下钻取“。”
如果你真的想要“地址”。 (因为你在你的例子中引用了一个Address类)来引用一个Address类型的对象,这有点复杂,你需要一些能够将前缀识别为类的东西,最好是一些自定义响应map的东西接口,可以在遍历树时轻松实例化,并知道如何从输入字符串创建自身对象。
我不确定beanutils实现的第一个细节是什么,写起来并不难。但嵌套的字符串映射很容易。您可以通过序列化(因为hashmaps和字符串序列化)或json库轻松打包它,这应该采用嵌套的字符串映射完全没有问题(google gson运行良好)。
答案 1 :(得分:0)
我认为你可能会比这更困难。我要做的是序列化标记或其他格式。我不确定你的要求是什么,但JAXB,XStream等所有优秀的编组人都是这样做的。
使用JAXB,您可以执行以下操作:
@XmlRootElement(name="customer")
public class Customer
{
private int id;
private Address address;
}
@XmlRootElement(name="address")
public class Address
{
private String city;
}
使用以下XML:
<customer>
<id>1234</id>
<address>
<city>Kansas City</city>
</address>
</customer>
......可以来回编组和解组。此外,JAXB marshaller还有其他一些实现(例如jersey-json),所以你也可以用其他格式编组:
{
"customer":
{
"id":1234,
"address":
{
"city":"Kansas City"
}
}
}
您是否需要使用地图?如果没有,你只是解决方案是一些复杂的Reflections实用程序,希望像GSON库这样的东西可以促进复杂性。
编辑:刚刚看到你想要映射的模糊......我真的不明白。使用序列化后,任何其他类似的方法似乎都不值得。