Избегайте десериализации строки json в gson для членов класса LinkedHashMap

В настоящее время, если я хочу избежать gson от десериализации строки json до LinkedHashMap, я бы использовал следующий код

HashMap<Integer, String> map = gson.fromJson(json_string,  new TypeToken<HashMap<Integer, String>>(){}.getType());

Однако у меня есть следующий класс

public static class Inventory {
    public Map<Integer, String> map1 = new HashMap<Integer, String>();
    public Map<Integer, String> map2 = new HashMap<Integer, String>();
}

Если я использую Inventory result = gson.fromJson(json_string, Inventory.class);, мой экземпляр Inventory будет иметь членов класса как LinkedHashMap.

Как я могу принудительно десериализовать строку json, чтобы иметь HashMap в качестве членов класса?

Вот пример рабочего кода

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.util.HashMap;
import java.util.Map;

/**
 *
 * @author yccheok
 */
public class Gson_tutorial {
    public static class Inventory {
        public Map<Integer, String> map1 = new HashMap<Integer, String>();
        public Map<Integer, String> map2 = new HashMap<Integer, String>();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        {
            Map<Integer, String> map= new HashMap<Integer, String>();
            map.put(2, "cake");

            final Gson gson = new GsonBuilder().create();
            final String json_string = gson.toJson(map);
            // {"2":"cake"}
            System.out.println(json_string);

            HashMap<Integer, String> result = gson.fromJson(json_string,  new TypeToken<HashMap<Integer, String>>(){}.getType());
            // class java.util.HashMap
            System.out.println(result.getClass());
        }

        {
            Inventory inventory = new Inventory();
            inventory.map1.put(2, "cake");
            inventory.map2.put(3, "donut");

            final Gson gson = new GsonBuilder().create();
            final String json_string = gson.toJson(inventory);
            // {"map1":{"2":"cake"},"map2":{"3":"donut"}}
            System.out.println(json_string);

            Inventory result = gson.fromJson(json_string,  Inventory.class);
            // class java.util.LinkedHashMap
            System.out.println(result.map1.getClass());
            // class java.util.LinkedHashMap
            System.out.println(result.map2.getClass());
        }
    }
}

person Cheok Yan Cheng    schedule 22.01.2015    source источник
comment
LinkedHashMap — это подкласс HashMap, поэтому, если вы получаете LinkedHashMap, у вас уже есть HashMap. В чем проблема?   -  person Hot Licks    schedule 23.01.2015


Ответы (1)


Объявите свои поля как HashMaps. Если не делать этого, вам нужно будет использовать собственный десериализатор.

Но если вы используете Map, какая вам разница, LinkedHashMap это или HashMap?

person Sotirios Delimanolis    schedule 22.01.2015
comment
Inventory — это сторонняя библиотека. В одной из функций Inventory выполнит приведение из Map в HashMap - person Cheok Yan Cheng; 22.01.2015
comment
@CheokYanCheng Ну, это не лучшая сторонняя библиотека :(. Gson не очень подходит для этого. Подумайте об использовании Jackson и его миксинов. - person Sotirios Delimanolis; 22.01.2015
comment
@CheokYanCheng Но HotLicks поднимает хороший вопрос в своем комментарии. LinkedHashMap является HashMap. Вы получаете что-то вроде ClassCastException? - person Sotirios Delimanolis; 23.01.2015
comment
Итак, какое решение здесь? Я использую gson.fromJson() с этим json: {"accountID":"cbeeeec4-4599-4a33-9e72-8a90d5ccd0e1.1459692534305" ,"cash":{"cashAvailableForTrade":8789.01,"cashAvailableForWithdrawal":8789.01,"cashBalance":8789.01}}. cash преобразуется в {cashAvailableForTrade=8789.01, cashAvailableForWithdrawal=8789.01, cashBalance=8789.01}. Как этого избежать и получить cash как HashMap? - person Shuwn Yuan Tee; 18.05.2016
comment
@shuwnyuantee Я не понимаю твоего вопроса. - person Sotirios Delimanolis; 18.05.2016