junfan / google-gson

Automatically exported from code.google.com/p/google-gson
0 stars 0 forks source link

integer values of array become a float values #559

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
public class Filter extends Object implements Serializable{

    private static final long serialVersionUID = 4944267946319467028L;  
    SparseArray<List<Integer>> catalogue = new SparseArray<List<String>>();

        ....
}

I'm filling catalogue variable with next values : {0=>{1,2,3,4}, 3=>{20,21,22} 
...}

Then I'm saving Filter object like this:
   ...
   ArrayList<Filter> filterList;
   .....

   public void saveFilter(Filter filterModel){      

      filterList.add(filterModel);

      Gson gson = new Gson();
      String jsonStr = gson.toJson(filterList);

      // For example save as
      preference = activity.getSharedPreferences("SJ_MAIN_STORAGE", Context.MODE_PRIVATE);
      Editor editor = preference.edit();
      editor.putString(key, jsonStr);       
      editor.commit();
   }    

I'm getting Filter object this way :
   public ArrayList<Filter> getFilter{
      Gson gson = new Gson();
      ArrayList<Filter> arrayList = new ArrayList<Filter>();    
      String json = preference.getString(key, "");
      if (hStrings.isEmpty(json)) return arrayList;

      JsonParser parser = new JsonParser();
      JsonArray array = parser.parse(json).getAsJsonArray();

      try{
    for(int i = 0; i < array.size(); i++)
    {
        arrayList.add(gson.fromJson(array.get(i), Filter.class));
    }
      }catch(Exception e){

      }
      return arrayList ;
   }

I have the next result of catalogue value: {0=>{1.0,2.0,3.0,4.0}, 
3=>{20.0,21.0,22.0} ...}

(integer values of array become a float values).
Is it right behavior?

Thank you.

Original issue reported on code.google.com by troshkov...@gmail.com on 12 Feb 2014 at 3:00

GoogleCodeExporter commented 9 years ago
Google Gson Version 2.2.4 

Original comment by troshkov...@gmail.com on 12 Feb 2014 at 3:04

GoogleCodeExporter commented 9 years ago
I have the same problem, How to treat object as integer first ?

    private static class ObjectLongFirstDeserializer
            implements JsonDeserializer<Object>
    {
        @Override
        public Object deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext ctx)
                throws JsonParseException
        {
            Object o = null;

            try{o = json.getAsLong();} catch (Exception ignored){}
            if (o == null)
            try{o = json.getAsDouble();} catch (Exception ignored){}
            if (o == null)
            try{o = json.getAsString();} catch (Exception ignored){}

            return o;
        }
    }

I have a deserializer, But It's not works.

Full Test

public class JsonTest
{
    private static class ObjectLongFirstDeserializer
            implements JsonDeserializer<Object>
    {
        @Override
        public Object deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext ctx)
                throws JsonParseException
        {
            Object o = null;

            try{o = json.getAsLong();} catch (Exception ignored){}
            if (o == null)
            try{o = json.getAsDouble();} catch (Exception ignored){}
            if (o == null)
            try{o = json.getAsString();} catch (Exception ignored){}

            return o;
        }
    }

    @Test
    public void test()
    {
        SimpleValue value = new SimpleValue();
        value.integer = 123;
        value.doubleFloat = 123.2;
        Gson gson = new GsonBuilder()
                .registerTypeAdapter(Object.class, new ObjectLongFirstDeserializer())
                .create();
        Object o = gson.fromJson(gson.toJson(value), new TypeToken<Map<String, Object>>() {}.getType());

        System.out.println(o);
    }

    public static class SimpleValue
    {
        Object integer;
        Object doubleFloat;
    }
}

Original comment by wenerm...@gmail.com on 25 Sep 2014 at 6:46

GoogleCodeExporter commented 9 years ago
BTW, Gson 2.3

Original comment by wenerm...@gmail.com on 25 Sep 2014 at 6:47

GoogleCodeExporter commented 9 years ago
I solved my problem 

public class JsonTest
{
    private static class IntegerFirstSOMapDeserializer
            implements JsonDeserializer<Map<String, Object>>
    {
        @Override
        public Map<String, Object> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext ctx)
                throws JsonParseException
        {
            Map<String, Object> map = Maps.newLinkedHashMap();
            for (Map.Entry<String, JsonElement> entry : json.getAsJsonObject().entrySet())
            {
                JsonElement el = entry.getValue();
                Object o = null;
                try
                {
                    float f = el.getAsFloat();
                    // not loose precision
                    if (Math.ceil(f) == f)
                        o = (int) f;
                    else o = f;
                } catch (Exception ignored) {}
                if (o == null)
                    try {o = el.getAsString();} catch (Exception ignored) {}
                map.put(entry.getKey(), o);
            }
            return map;
        }
    }

    @Test
    public void test()
    {
        Map<String,Object> value = Maps.newHashMap();
        value.put("i",123);
        value.put("d",123.2f);
        Gson gson = new GsonBuilder()
                .registerTypeAdapter(new TypeToken<Map<String, Object>>() {}.getType(), new IntegerFirstSOMapDeserializer())
                .create();

        Map o = gson.fromJson(gson.toJson(value), new TypeToken<Map<String, Object>>() {}.getType());
        System.out.println(o);
        assert o.get("i").equals(value.get("i"));
        assert o.get("d").equals(value.get("d"));
        o = gson.fromJson(gson.toJson(value), new TypeToken<Map<String, Float>>() {}.getType());
        System.out.println(o);
        assert !o.get("i").equals(value.get("i"));
        assert o.get("d").equals(value.get("d"));
    }
}

Original comment by wenerm...@gmail.com on 25 Sep 2014 at 7:45

GoogleCodeExporter commented 9 years ago
// not loose precision

You do as an int does not fit exactly in a float. Run your test with something 
like Integer.MAX_VALUE-2.

Original comment by Maaarti...@gmail.com on 29 Sep 2014 at 6:53