Java如何保留Map<String,Object>中Double的小数部分(非字符串形式)
解决方案
问题本质是JSON序列化工具(比如Spring Boot默认的Jackson)会将值为整数的Double(如0.0、1.0)自动优化为整数格式输出,导致Swagger返回0而非0.0。要维持原Map结构且保留数值格式的小数部分,可通过以下方式处理:
1. 全局配置Jackson(Spring Boot场景)
如果项目使用Jackson作为JSON序列化工具,可通过自定义ObjectMapper强制保留Double的小数格式:
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.module.SimpleModule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.io.IOException; @Configuration public class JacksonConfig { @Bean public ObjectMapper objectMapper() { ObjectMapper objectMapper = new ObjectMapper(); SimpleModule doubleModule = new SimpleModule(); // 自定义Double序列化器,避免整数优化 doubleModule.addSerializer(Double.class, new JsonSerializer<Double>() { @Override public void serialize(Double value, JsonGenerator gen, SerializerProvider serializers) throws IOException { if (value == null) { gen.writeNull(); return; } // 直接写入原始double值的字符串形式,确保JSON输出为带小数的数值 gen.writeRaw(String.valueOf(value)); } }); objectMapper.registerModule(doubleModule); return objectMapper; } }
这个配置会让所有Double类型值(包括嵌套在List、Map中的元素)都以带小数的数值格式输出,比如0.0会被序列化为0.0而非0,且保持数值类型而非字符串。
2. 针对特定Map的局部处理
如果不想全局修改,可手动遍历Map和嵌套的List,将整数型Double替换为BigDecimal(因为BigDecimal序列化时会保留小数位数):
import java.math.BigDecimal; import java.util.List; import java.util.Map; public class MapProcessor { public static void processMap(Map<String, Object> map) { for (Map.Entry<String, Object> entry : map.entrySet()) { Object value = entry.getValue(); if (value instanceof List) { processList((List<?>) value); } else if (value instanceof Map) { processMap((Map<String, Object>) value); } else if (value instanceof Double) { Double doubleVal = (Double) value; // 将整数型Double转为带小数的BigDecimal if (doubleVal % 1 == 0) { entry.setValue(new BigDecimal(doubleVal).setScale(1)); } } } } private static void processList(List<?> list) { for (int i = 0; i < list.size(); i++) { Object item = list.get(i); if (item instanceof List) { processList((List<?>) item); } else if (item instanceof Map) { processMap((Map<String, Object>) item); } else if (item instanceof Double) { Double doubleVal = (Double) item; if (doubleVal % 1 == 0) { list.set(i, new BigDecimal(doubleVal).setScale(1)); } } } } }
返回结果前调用processMap(yourMap)即可,BigDecimal序列化后会输出0.0这样的数值格式,且不会改变原Map的整体结构。
注意事项
- 不要使用
DecimalFormat,因为它返回的是字符串,不符合你需要的数值格式要求。 - 如果项目使用Fastjson作为序列化工具,可配置
SerializerFeature.WriteBigDecimalAsPlain,并将Double转换为BigDecimal实现同样效果。
内容的提问来源于stack exchange,提问作者Dmitry
相关产品推荐
相关产品推荐

