使GSON反序列化数字为整数或双精度
我很难与GSON合作。
我有一个简单的JSON,我想反序列化为一个Map<String,Object>
。
我认为123应该被解析为int(或long),123.4被解析为float(或double)。
另一方面,GSON一直在创造双打。
我可以告诉GSON不要一直滥用双倍吗?
我的实际代码:
Type mapType = new TypeToken<Map<String, Object>>() {}.getType();
GSON gson = new Gson();
Map<String, Object> map = gson.fromJson(someString, mapType);
以下代码编译和工作:
package test;
import java.lang.reflect.Type;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.reflect.TypeToken;
public class Main {
public static void main(String[] args) {
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(Object.class, new MyObjectDeserializer());
Gson gson = builder.create();
String array = "[1, 2.5, 4, 5.66]";
Type objectListType = new TypeToken<ArrayList<Object>>() {}.getType();
List<Object> obj = gson.fromJson(array, objectListType);
System.out.println(Arrays.toString(obj.toArray()));
}
public static class MyObjectDeserializer implements JsonDeserializer<Object> {
public Object deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
Number num = null;
try {
num = NumberFormat.getInstance().parse(json.getAsJsonPrimitive().getAsString());
} catch (Exception e) {
//ignore
}
if (num == null) {
return context.deserialize(json, typeOfT);
} else {
return num;
}
}
}
}
我的解决方案将首先尝试将字符串解析为数字,如果失败,它会让标准的Gson解串器完成工作。
如果您需要一个不是区域设置特定的数字解析器,请使用此方法解析数字:
private static Number parse(String str) {
Number number = null;
try {
number = Float.parseFloat(str);
} catch(NumberFormatException e) {
try {
number = Double.parseDouble(str);
} catch(NumberFormatException e1) {
try {
number = Integer.parseInt(str);
} catch(NumberFormatException e2) {
try {
number = Long.parseLong(str);
} catch(NumberFormatException e3) {
throw e3;
}
}
}
}
return number;
}
您可以进行以下更改以解析数据:
testData1={"GOAL1":123, "GOAL2":123.45,"GOAL5":1256,"GOAL6":345.98}
下面是你的代码来实际解析它。
Type mapType = new TypeToken<Map<String, Object>>() {
}.getType();
String str = prop.getProperty("testData1");
System.out.println(str);
Gson gson = new Gson();
Map<String, Object> map = gson.fromJson(str, mapType);
for (String key : map.keySet()) {
String a = null;
try {
if (map.get(key) instanceof Double) {
a = "" + map.get(key);
} else {
if (map.get(key) instanceof String) {
a = (String) map.get(key);
} else {
a = null;
}
}
if (a != null && a.contains(".") && !a.endsWith(".0")) {
// Convert it into Double/Float
} else {
// Work as Integer
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
将这种类型混合(整数与双打)并不是一个好主意。 由于您将Object用作类型,因此您无法从地图中获取整数和双精度。 Gson决定哪种类型更适合Object。 在你的情况下,它是双精度,因为所有值都可以加倍,但是所有的值都不能是整数。
如果您确实需要混合类型,请尝试使用Number类而不是Object。 例:
public static void main(String[] args){
String array = "[1, 2.5, 4, 5.66]";
Gson gson = new Gson();
Type type = new TypeToken<ArrayList<Number>>() {}.getType();
List<Number> obj = gson.fromJson(array, type);
System.out.println(Arrays.toString(obj.toArray()));
}
输出:[1,2.5,4,5.66]
虽然这样:
public static void main(String[] args){
String array = "[1, 2.5, 4, 5.66]";
Gson gson = new Gson();
Type type = new TypeToken<ArrayList<Object>>() {}.getType();
List<Object> obj = gson.fromJson(array, type);
System.out.println(Arrays.toString(obj.toArray()));
}
会给你输出:[1.0,2.5,4.0,5.66]
链接地址: http://www.djcxy.com/p/80653.html上一篇: Make GSON deserialize numbers to integers or doubles
下一篇: How do I use parameter overloading or optional parameters in rust?