2013-05-07 27 views

回答

160

那麼,你也可以用傑克遜來實現。 (因爲你正在考慮使用傑克遜似乎更舒服)。

使用ObjectMapperconvertValue方法:

final ObjectMapper mapper = new ObjectMapper(); // jackson's objectmapper 
final MyPojo pojo = mapper.convertValue(map, MyPojo.class); 

無需轉換成JSON字符串或別的東西;直接轉換的速度要快得多。

+0

你能提供這個庫的gradle命令嗎? – 2016-12-25 20:29:42

+2

您需要包含此庫才能使用ObjectMapper'compile'c​​om.fasterxml.jackson.core:jackson-databind:2.7.3'' – 2016-12-25 20:31:22

+1

使用convertValue是正確答案,但不要每次都創建一個ObjectMapper實例。創建和線程安全代價很高,因此創建一個並將其緩存在某處。 – glade 2017-02-26 23:06:46

2

是的,它絕對有可能避免中間轉換爲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>只能獲得一個級別)。

+0

謝謝 - 非常有幫助。 – user86834 2013-05-07 22:20:11

+1

你怎麼能做一個從地圖到POJO的「深層複製」?比如說你有一個User.class封裝了一個Address.class,並且這個地圖有一個像「address.city」,「address.zip」這樣的密鑰,這些需要映射到User.Address.City和User.Address.Zip ?它似乎沒有自動將Map鍵中的點解釋爲對象圖的子級別。 – szxnyc 2015-08-07 21:51:55

20

Gson A液:

Gson gson = new Gson(); 
JsonElement jsonElement = gson.toJsonTree(map); 
MyPojo pojo = gson.fromJson(jsonElement, MyPojo.class); 
+1

真棒!!!!!!!! – TechBee 2018-01-09 16:40:37

3

我已經測試了傑克遜和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)); 
}} 
+0

區別在於:傑克遜擁有一個完整的類型轉換框架。例如'Map'包含'map.put(「data」,「2016-06-26」)並且'TestClass'有一個字段'private LocalDate data;',那麼Jackson將能夠完成任務,而BeanUtils將會失敗。 – 2016-06-26 10:00:44

相關問題