Java 使用gson在反序列化期间格式化嵌套对象中的双精度值
试图实现从json反序列化时保留4个小数点格式。现在它只得到一个小数点,例如1800.0。这是需要反序列化的json字符串:Java 使用gson在反序列化期间格式化嵌套对象中的双精度值,java,json,gson,Java,Json,Gson,试图实现从json反序列化时保留4个小数点格式。现在它只得到一个小数点,例如1800.0。这是需要反序列化的json字符串: { "root": [ { "paymentType": [ { "listPrice": 1800.0000 } ] } ] } 我有以下课程: public class Root { ... publ
{
"root": [
{
"paymentType": [
{
"listPrice": 1800.0000
}
]
}
]
}
我有以下课程:
public class Root {
...
public List<Package> package;
}
我想将listPrice的格式设置为保留四个小数点。它现在被截断为.0
gson序列化代码:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(new TypeToken<Double>() {}.getType(), new DoubleDeserializer());
Gson gson = gsonBuilder.create();
Root root = gson.fromJson(rawJson, Root.class);
但得到同样的结果:1800.0。这是由于在getAsDouble()或json值1800.0000的任何其他解析方法中进行了转换。应用格式时,该值从一开始就是1800.0,这使得格式冗余。有什么办法对付这个吗
最终更新:通过将PaymentType和格式中listPrice的Double类型更改为BigDecimal类型来解决(感谢@JoopEggen),使用:
BigDecimal formattedListPrice =
paymentType.get("listPrice").getAsBigDecimal().setScale(4, RoundingMode.CEILING);
谢谢大家! 这回答了你的问题吗?没有拖行0的双精度浮点型与拖行0为无穷大的双精度浮点型相同。数学表示法与字符串(人类可读)表示法不同,我的意思是没有理由设置比例,然后获得双精度值,因为double没有比例参数,因此在转换过程中会丢失信息。从数学上讲,1800.0等于1800.00,等于1800.0000甚至1800.000000000。关注文本格式值得一提。无论json中的文本是什么,文本1.2345可能不是该值,而是带有一个小近似错误的近似值。由于浮点没有精度,只需切换到非常详细的BigDecimal。是的,而不是Double/Double。并且不使用双构造函数,而是使用新的BigDecimal(“1.8000”)来提供精度。
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(new TypeToken<Double>() {}.getType(), new DoubleDeserializer());
Gson gson = gsonBuilder.create();
Root root = gson.fromJson(rawJson, Root.class);
public class DoubleDeserializer implements JsonDeserializer<Double> {
@Override
public Double deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
return json.getAsBigDecimal().setScale(4, RoundingMode.DOWN).doubleValue();
}
}
public PaymentType deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
JsonObject paymentType = json.getAsJsonObject();
if (isValid(paymentType)) {
double listPrice = paymentType.get("listPrice").getAsDouble();
DecimalFormat df = (DecimalFormat) NumberFormat.getNumberInstance(Locale.ROOT);
df.applyPattern("#0.0000");
double formattedListPrice = Double.parseDouble(df.format(listPrice));
PaymentType formattedPaymentType = new PaymentType();
formattedPaymentType.listPrice = formattedListPrice;
return formattedPaymentType;
}
return new Gson().fromJson(json, PaymentType.class);
}
BigDecimal formattedListPrice =
paymentType.get("listPrice").getAsBigDecimal().setScale(4, RoundingMode.CEILING);