gpt4 book ai didi

java - jackson - 具有受控精度的 double json 编码

转载 作者:搜寻专家 更新时间:2023-10-31 20:15:21 26 4
gpt4 key购买 nike

我正在使用 double 值数组对一个复杂的 Map 结构进行编码。高精度并不重要,输出大小很重要,因此我试图让 JSON 工具(在本例中为 Jackson)使用提供的 DecimalFormat 序列化 double 值。

以下是我最好的镜头,但由于对象映射器未选择序列化程序来对数组进行编码,因此失败了:

class MyTest
{
public class MyDoubleSerializer extends JsonSerializer<double[]>
{
public void serialize(double[] value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException
{
for (double d : value)
{
jgen.writeStartArray();
jgen.writeRaw( df.format( d ) );
jgen.writeEndArray();
}
}
}

@Test
public void test1() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule("MyModule", new Version(0, 1, 0, "alpha"));
module.addSerializer(double[].class, new MyDoubleSerializer());
mapper.registerModule(module);

Map<String, Object> data = new HashMap<String, Object>();
double[] doubleList = { 1.1111111111D, (double) (System.currentTimeMillis()) };
data.put( "test", doubleList );
System.out.print( mapper.writeValueAsString( data ));
}
}

输出是:

{"test":[1.1111111111,1.315143204964E12}

我在找什么:

{"test":[1.32E12, 1.11E0]}

有什么想法吗?

此外,我不喜欢必须生成一个 String 并且写入是原始的 - 我可以将 StringBuffer 馈送到 DecimalFormat 中来执行此操作吗?

谢谢

最佳答案

通过借用 Double 的内置序列化器设法解决了这个问题。

这有点麻烦,因为 writeRaw() 不关心上下文并且不在数组成员之间写逗号,所以我转换 Json writer 并调用它的 writeValue() 方法来处理这个.

奇怪的是,这不适用于问题中的示例(同样不会被要求序列化这些 double ),但确实适用于我更复杂的真实世界对象。

享受...

public class JacksonDoubleArrayTest
{
private DecimalFormat df = new DecimalFormat( "0.##E0" );

public class MyDoubleSerializer extends org.codehaus.jackson.map.ser.ScalarSerializerBase<Double>
{
protected MyDoubleSerializer()
{
super( Double.class );
}

@Override
public final void serializeWithType( Double value, JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer ) throws IOException,
JsonGenerationException
{
serialize( value, jgen, provider );
}

@Override
public void serialize( Double value, JsonGenerator jgen, SerializerProvider provider ) throws IOException, JsonGenerationException
{
if ( Double.isNaN( value ) || Double.isInfinite( value ) )
{
jgen.writeNumber( 0 ); // For lack of a better alternative in JSON
return;
}

String x = df.format( value );
if ( x.endsWith( "E0" ) )
{
x = x.substring( 0, x.length() - 2 );
}
else if ( x.endsWith( "E1" ) && x.length() == 6 )
{
x = "" + x.charAt( 0 ) + x.charAt( 2 ) + '.' + x.charAt( 3 );
}
JsonWriteContext ctx = (JsonWriteContext)jgen.getOutputContext();
ctx.writeValue();
if ( jgen.getOutputContext().getCurrentIndex() > 0 )
{
x = "," + x;
}
jgen.writeRaw( x );
}

@Override
public JsonNode getSchema( SerializerProvider provider, Type typeHint )
{
return createSchemaNode( "number", true );
}
}

@SuppressWarnings("unchecked")
private static Map<String, Object> load() throws JsonParseException, JsonMappingException, IOException
{
ObjectMapper loader = new ObjectMapper();
return (Map<String, Object>)loader.readValue( new File( "x.json" ), Map.class );
}

@Test
public void test1() throws JsonGenerationException, JsonMappingException, IOException
{
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule( "StatsModule", new Version( 0, 1, 0, "alpha" ) );
module.addSerializer( Double.class, new MyDoubleSerializer() );
mapper.registerModule( module );
String out = mapper.writeValueAsString( load() );
// System.out.println( out.length() );
}
}

关于java - jackson - 具有受控精度的 double json 编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7299576/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com