已运行的大型项目中,字符串转Map使用Gson工具类进行转换,不敢贸然使用其它工具类(如FastJson),这是前提。
如果你是学习或者小型项目,Gson使用出现浮点转换科学记数法的问题,可以换成FastJson 工具或者其它工具,就能解决此问题。
String jsonStr="{\"data\":0.000001}";
Map<String,Object> jsonMap= JsonUtil.jsonStrToMap(jsonStr);
System.out.println(jsonMap.toString());
运行结果
{nc=1.0E-6}
Java Map 对象存放数据时,会自动将浮点类型变成科学记数法。
Map map =new HashMap();
map.put("a",0.000001);
运行结果
{a=1.0E-6}
Map 对象存放 BigDecimal 数据时,会保持原数据。
Map map =new HashMap();
map.put("a",0.000001);
map.put("b",new BigDecimal("0.000002"));
System.out.println(map.toString());
运行结果:
{a=1.0E-6, b=0.000002}
使用Gson进行Json字符串与Java Map对象间转换时,Json字符串里 如果是numberic(double、long、int),Gson会在转成java对象时将该属性默认认为是Double类型,就会出现变成科学记数法的问题。
解决方法是进行数据进行保装。
1、gson反序列化适配器
import com.google.gson.*;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* 用于解决当Json字符串中含用浮点类型(如0.0000004)值,在反序列化转换成Map时,会变成科学记数法的问题
*/
public class GsonDoubleAdapter implements JsonDeserializer<HashMap<String, Object>> {
@Override
public HashMap<String, Object> deserialize(JsonElement json,Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
HashMap<String, Object> dataMap = new HashMap<>();
JsonObject jsonObject = json.getAsJsonObject();
Set<Map.Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
for (Map.Entry<String, JsonElement> entry : entrySet) {
Object ot = entry.getValue();
if(ot instanceof JsonPrimitive){
dataMap.put(entry.getKey(), ((JsonPrimitive) ot).getAsString());
}else{
dataMap.put(entry.getKey(), ot);
}
}
return dataMap;
}
}
2、在创建 gson对象时,添加适配置器:
static Type typeToken = new TypeToken<HashMap<String, Object>>(){}.getType();
static Gson gson= new GsonBuilder()
.serializeNulls()//
.registerTypeAdapter(typeToken,new GsonDoubleAdapter())//此行为新增加的适配器
.disableHtmlEscaping()//
.create();
3、json字符串转Map对象的方法也要修改,如下:
gson.fromJson(jsonStr, typeToken);
String jsonStr="{\"nc\":0.000001}";
Map<String,Object> jsonMap= JsonUtil.jsonStrToMap(jsonStr);
System.out.println(jsonMap.toString());
运行结果:
{nc=0.000001}