众所周知,Map的KeySet不可序列化。但我有一些情况,我只想通过网络发送包裹在自定义对象中的地图的KeySet。所以我已经实现了writeObject方法来检查可序列化的Set。
我现在的问题是,如果有办法获得二进制表示而不将整个Set复制到一个新的Set中?这对我来说效率非常低,因为在这种情况下我们通常有大量的地图(这是我们发送密钥而不是整个地图的原因之一)。
public class Serialize2 implements Serializable {
private static final Class TM_KS_CLASS = new TreeMap<>().keySet().getClass();
private static final Class LM_KS_CLASS = new LinkedHashMap<>().keySet().getClass();
private Set<String> testSet;
public String justSomeOtherFieldToSerialize;
public Serialize2(Set<String> testSet) {
this.testSet = testSet;
}
public Set<String> getTestSet() {
return testSet;
}
private void writeObject(java.io.ObjectOutputStream stream) throws java.io.IOException {
if (!(testSet instanceof Serializable)) {
if (testSet.getClass().equals(TM_KS_CLASS)) {
testSet = new TreeSet<>(testSet);
} else {
testSet = new HashSet<>(testSet);
}
}
stream.defaultWriteObject();
}
@Override
public String toString() {
return "Serialize2{" +
"testSet=" + testSet +
'}';
}
public static void main(String[] args) {
Map<String, Integer> foo = new HashMap<>();
foo.put("lala", 1);
foo.put("lolo", 2);
foo.put("lulu", 3);
foo.put("lili", 4);
Serialize2 sTest = new Serialize2(foo.keySet());
Serialize2 dsTest = (Serialize2) SerializationUtils.deserialize(SerializationUtils.serialize(sTest));
System.out.println(dsTest);
}
}
答案 0 :(得分:1)
是的,一种方法是单独序列化每个对象而不复制到新的集合中,
private void writeObject(java.io.ObjectOutputStream stream) throws java.io.IOException {
Iterator itr = testSet.iterator();
if (testSet.getClass().equals(TM_KS_CLASS)) {
stream.writeBoolean(true);
} else {
stream.writeBoolean(false);
}
stream.writeInt(testSet.size());
while(itr.hasNext()) {
stream.writeObject(itr.next());
}
stream.writeObject(justSomeOtherFieldToSerialize);
}
您需要具有相应的readObject实现,该实现分别读取每个对象并放入一个集合,例如
private void readObject(java.io.ObjectInputStream stream) throws java.io.IOException {
boolean bTypeofmap = stream.readBoolean(); // Whether its a TreeMap or LinkedhashMap
int size = stream.readInt();
testSet = new java.util.HashSet(size);
for(int i = 0; i < size; i++) {
testSet.add(stream.readObject());
}
justSomeOtherFieldToSerialize = (String) stream.readObject();
}