我想以 JSON 格式序列化/反序列化 java.util.Bitset。 此代码:
BitSet bs = new BitSet(10);
bs.set(1);
bs.set(5);
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(System.out, bs);
打印 {"empty":false} 作为输出。 我应该编写自己的序列化器/反序列化器还是有更好的方法?
ObjectMapper.writeValue() 将查找对象类并找到所有 getSomething 方法和 isSomething 方法,并根据方法名称生成 json。
您的结果 {"empty":false} 来自 BitSet 类的此方法:
public boolean isEmpty() {...}
所以我认为你应该编写自己的序列化器/反序列化器,而不是使用 ObjectMapper 序列化机制
谢谢!我认为,我有一个解决方案,对我来说似乎可以节省更多空间和内存 - 由于处理大量数据,这很重要。以下解决方案做到了:
public class BitSetSerializer extends JsonSerializer<BitSet>
{
@Override
public void serialize(BitSet value, JsonGenerator gen, SerializerProvider serializers)
throws IOException, JsonProcessingException
{
gen.writeStartArray();
for (long l : value.toLongArray())
{
gen.writeNumber(l);
}
gen.writeEndArray();
}
@Override
public Class<BitSet> handledType()
{
return BitSet.class;
}
}
public class BitSetDeserializer extends JsonDeserializer<BitSet>
{
@Override
public BitSet deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
throws IOException, JsonProcessingException
{
ArrayList<Long> l = new ArrayList<Long>();
JsonToken token;
while (!JsonToken.END_ARRAY.equals(token = jsonParser.nextValue()))
{
if (token.isNumeric())
{
l.add(jsonParser.getLongValue());
}
}
return BitSet.valueOf(Longs.toArray(l));
}
}
SimpleModule testModule = new SimpleModule("MyModule");
testModule.addSerializer(new BitSetSerializer());
testModule.addDeserializer(BitSet.class, new BitSetDeserializer());
BitSet bs = new BitSet();
bs.set(1);
bs.set(1500);
System.out.println(bs);
ObjectMapper mapper = new ObjectMapper();
// mapper.registerModule(new Jdk8Module()); //serialization result takes too much space
mapper.registerModule(testModule);
String val = mapper.writeValueAsString(bs);
System.out.println(val);
BitSet bs2 = mapper.readValue(val, BitSet.class);
System.out.println(bs2);
尝试使用 Bitset 的自定义序列化器和解串器。
序列化器:
public class BitSetSerializer extends JsonSerializer<BitSet> {
@Override
public void serialize(BitSet value, JsonGenerator gen,
SerializerProvider serializers) throws IOException, JsonProcessingException {
gen.writeStartArray();
for (int i = 0; i < value.length(); i++) {
gen.writeBoolean(value.get(i));
}
gen.writeEndArray();
}
}
反串器:
public class BitSetDeserializer extends JsonDeserializer<BitSet> {
@Override
public BitSet deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
throws IOException, JsonProcessingException {
BitSet ret = new BitSet();
int i = 0;
JsonToken token;
while (!JsonToken.END_ARRAY.equals(token = jsonParser.nextValue())) {
if (JsonToken.VALUE_TRUE.equals(token))
ret.set(i);
i++;
}
return ret;
}
}
`导入 org.json.JSONException; 导入 org.json.JSONObject; 导入 java.util.BitSet;
公共类 JSONBitSetConverter {
// Convert JSON string to BitSet
public static BitSet jsonToBitSet(String jsonString) {
BitSet bitSet = new BitSet();
try {
JSONObject jsonObject = new JSONObject(jsonString);
String[] keys = JSONObject.getNames(jsonObject);
if (keys != null) {
for (String key : keys) {
int index = Integer.parseInt(key);
boolean value = jsonObject.getBoolean(key);
bitSet.set(index, value);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return bitSet;
}
// Convert BitSet to JSON string
public static String bitSetToJSON(BitSet bitSet) {
JSONObject jsonObject = new JSONObject();
for (int i = bitSet.nextSetBit(0); i >= 0; i = bitSet.nextSetBit(i + 1)) {
try {
jsonObject.put(Integer.toString(i), bitSet.get(i));
} catch (JSONException e) {
e.printStackTrace();
}
}
return jsonObject.toString();
}
public static void main(String[] args) {
String jsonString = "{\"0\":true,\"2\":true,\"3\":true}";
BitSet bitSet = jsonToBitSet(jsonString);
System.out.println("BitSet: " + bitSet);
String newJsonString = bitSetToJSON(bitSet);
System.out.println("JSON String: " + newJsonString);
}
}