回答:
まあ、あなたはジャクソンでもそれを達成することができます。(そして、あなたはジャクソンの使用を考えていたので、それはより快適なようです)。
ObjectMapper
のconvertValue
メソッドを使用:
final ObjectMapper mapper = new ObjectMapper(); // jackson's objectmapper
final MyPojo pojo = mapper.convertValue(map, MyPojo.class);
JSON文字列などに変換する必要はありません。直接変換ははるかに高速です。
Map<String, Object>
インスタンスにディープ変換する方法を理解しましたか?
Gsonによるソリューション:
Gson gson = new Gson();
JsonElement jsonElement = gson.toJsonTree(map);
MyPojo pojo = gson.fromJson(jsonElement, MyPojo.class);
map.toString()
正しい文字列を提供すると思いますか?の実装はtoString()
、特定の形式を保証するものではありません。
はい、JSONへの中間変換を回避することは間違いなく可能です。Dozerなどのディープコピーツールを使用すると、マップを直接POJOに変換できます。これは単純な例です:
POJOの例:
public class MyPojo implements Serializable {
private static final long serialVersionUID = 1L;
private String id;
private String name;
private Integer age;
private Double savings;
public MyPojo() {
super();
}
// Getters/setters
@Override
public String toString() {
return String.format(
"MyPojo[id = %s, name = %s, age = %s, savings = %s]", getId(),
getName(), getAge(), getSavings());
}
}
変換コードの例:
public class CopyTest {
@Test
public void testCopyMapToPOJO() throws Exception {
final Map<String, String> map = new HashMap<String, String>(4);
map.put("id", "5");
map.put("name", "Bob");
map.put("age", "23");
map.put("savings", "2500.39");
map.put("extra", "foo");
final DozerBeanMapper mapper = new DozerBeanMapper();
final MyPojo pojo = mapper.map(map, MyPojo.class);
System.out.println(pojo);
}
}
出力:
MyPojo [ID = 5、名前=ボブ、年齢= 23、貯蓄= 2500.39]
注:ソースマップをに変更すると、Map<String, Object>
任意に深いネストされたプロパティをコピーできます(Map<String, String>
1つのレベルしか取得できません)。
あなたのクラスでジェネリック型を持っている場合は使用すべきであるTypeReference
とconvertValue()
。
final ObjectMapper mapper = new ObjectMapper();
final MyPojo<MyGenericType> pojo = mapper.convertValue(map, new TypeReference<MyPojo<MyGenericType>>() {});
また、それを使用してpojoをjava.util.Map
back に変換することもできます。
final ObjectMapper mapper = new ObjectMapper();
final Map<String, Object> map = mapper.convertValue(pojo, new TypeReference<Map<String, Object>>() {});
JacksonとBeanUtilsの両方をテストしたところ、BeanUtilsの方がはるかに高速であることがわかりました。
私のマシン(Windows8.1、JDK1.7)では、この結果が得られました。
BeanUtils t2-t1 = 286
Jackson t2-t1 = 2203
public class MainMapToPOJO {
public static final int LOOP_MAX_COUNT = 1000;
public static void main(String[] args) {
Map<String, Object> map = new HashMap<>();
map.put("success", true);
map.put("data", "testString");
runBeanUtilsPopulate(map);
runJacksonMapper(map);
}
private static void runBeanUtilsPopulate(Map<String, Object> map) {
long t1 = System.currentTimeMillis();
for (int i = 0; i < LOOP_MAX_COUNT; i++) {
try {
TestClass bean = new TestClass();
BeanUtils.populate(bean, map);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
long t2 = System.currentTimeMillis();
System.out.println("BeanUtils t2-t1 = " + String.valueOf(t2 - t1));
}
private static void runJacksonMapper(Map<String, Object> map) {
long t1 = System.currentTimeMillis();
for (int i = 0; i < LOOP_MAX_COUNT; i++) {
ObjectMapper mapper = new ObjectMapper();
TestClass testClass = mapper.convertValue(map, TestClass.class);
}
long t2 = System.currentTimeMillis();
System.out.println("Jackson t2-t1 = " + String.valueOf(t2 - t1));
}}
Map
含まれているmap.put("data","2016-06-26")
とTestClass
フィールドを持ちprivate LocalDate data;
、そしてジャクソンは々 BeanUtilsは失敗しながら物事は、成し遂げることができるでしょう。
ObjectMapper
インスタンスの作成は時間とリソースを消費するプロセスであると聞きました。毎回新しく作成するのではなく、1つのマッパーインスタンスを再利用することをお勧めします。私はテスト
これまでにJacksonを使用して提供された回答は非常に優れていますが、次のように異なるs を変換するのに役立つutil関数を使用できます。POJO
public static <T> T convert(Map<String, Object> aMap, Class<T> t) {
try {
return objectMapper
.convertValue(aMap, objectMapper.getTypeFactory().constructType(t));
} catch (Exception e) {
log.error("converting failed! aMap: {}, class: {}", getJsonString(aMap), t.getClass().getSimpleName(), e);
}
return null;
}
MapをPOJOの例に変換します。Mapキーに下線が含まれ、フィールド変数がhumpであることに注意してください。
User.class POJO
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class User {
@JsonProperty("user_name")
private String userName;
@JsonProperty("pass_word")
private String passWord;
}
App.classで例をテストする
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper;
public class App {
public static void main(String[] args) {
Map<String, String> info = new HashMap<>();
info.put("user_name", "Q10Viking");
info.put("pass_word", "123456");
ObjectMapper mapper = new ObjectMapper();
User user = mapper.convertValue(info, User.class);
System.out.println("-------------------------------");
System.out.println(user);
}
}
/**output
-------------------------------
User(userName=Q10Viking, passWord=123456)
*/
@Hamedz多くのデータを使用する場合は、Jacksonを使用してライトデータを変換し、Apacheを使用してください... TestCase:
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
public class TestPerf {
public static final int LOOP_MAX_COUNT = 1000;
public static void main(String[] args) {
Map<String, Object> map = new HashMap<>();
map.put("success", true);
map.put("number", 1000);
map.put("longer", 1000L);
map.put("doubler", 1000D);
map.put("data1", "testString");
map.put("data2", "testString");
map.put("data3", "testString");
map.put("data4", "testString");
map.put("data5", "testString");
map.put("data6", "testString");
map.put("data7", "testString");
map.put("data8", "testString");
map.put("data9", "testString");
map.put("data10", "testString");
runBeanUtilsPopulate(map);
runJacksonMapper(map);
}
private static void runBeanUtilsPopulate(Map<String, Object> map) {
long t1 = System.currentTimeMillis();
for (int i = 0; i < LOOP_MAX_COUNT; i++) {
try {
TestClass bean = new TestClass();
BeanUtils.populate(bean, map);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
long t2 = System.currentTimeMillis();
System.out.println("BeanUtils t2-t1 = " + String.valueOf(t2 - t1));
}
private static void runJacksonMapper(Map<String, Object> map) {
long t1 = System.currentTimeMillis();
for (int i = 0; i < LOOP_MAX_COUNT; i++) {
ObjectMapper mapper = new ObjectMapper();
TestClass testClass = mapper.convertValue(map, TestClass.class);
}
long t2 = System.currentTimeMillis();
System.out.println("Jackson t2-t1 = " + String.valueOf(t2 - t1));
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class TestClass {
private Boolean success;
private Integer number;
private Long longer;
private Double doubler;
private String data1;
private String data2;
private String data3;
private String data4;
private String data5;
private String data6;
private String data7;
private String data8;
private String data9;
private String data10;
}
}
compile 'com.fasterxml.jackson.core:jackson-databind:2.7.3'