我正在尝试序列化InstitutionResultView类的一些对象,它基本上是guava's TreeMultimap的包装:
import java.io.Serializable;
import java.text.Collator;
import java.util.Comparator;
import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.collect.Maps.EntryTransformer;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Ordering;
import com.google.common.collect.SortedSetMultimap;
import com.google.common.collect.TreeMultimap;
public class InstitutionResultView implements Serializable {
private static final long serialVersionUID = -8110992296090587657L;
private final SortedSetMultimap<String, Institution> nameToInstitutionsMapping = TreeMultimap.create(
Ordering.from(StringComparators.AS_IS), // insertion order
Ordering.natural() // <----- this works when serializing object
// Ordering.from(Collator.getInstance()) // <----- when used instead previous line gives an exception when serializing
.nullsFirst().onResultOf(StringInstitutionFunctions.BY_NAME) // sort by name
.compound(
Ordering.natural().nullsFirst().onResultOf(IntegerInstitutionFunctions.BY_ID) // sort by id
));
public SortedSetMultimap<String, Institution> institutions() {
return nameToInstitutionsMapping;
}
public void setInstitutions(final Multimap<String, Institution> institutions) {
this.nameToInstitutionsMapping.clear();
this.nameToInstitutionsMapping.putAll(institutions);
}
@Override
public String toString() {
return Objects.toStringHelper(this)
.add("nameToInstitutionsMapping", Multimaps.transformEntries(nameToInstitutionsMapping, EntryTransformers.TO_NAME_WITH_CATEGORY))
.toString();
}
在序列化期间,我得到例外:
java.io.NotSerializableException:java.text.RuleBasedCollator at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164) 在
...
com.google.common.collect.TreeMultimap.writeObject(TreeMultimap.java:180)
...
我发现this bug from Sun's bug database涵盖了与我非常相似的案例,但它没有指出任何解决方案。我尝试添加瞬态Collator实例字段:
private transient Collator collatorInstance = Collator.getInstance();
并将其用作Ordering.from(collatorInstance)
但仍不起作用。
如果有人能告诉我如何解决这个问题,我会很高兴。
编辑 - 这对我有用(感谢@Puce和他的回答):
class CollatorWrapper implements Comparator<String>, Serializable {
private static final long serialVersionUID = 1L;
private transient Collator collatorInstance;
public CollatorWrapper() {
super();
initCollatorInstance();
}
@Override
public int compare(final String o1, final String o2) {
return collatorInstance.compare(o1, o2);
}
private void initCollatorInstance() {
collatorInstance = Collator.getInstance();
}
private void writeObject(final java.io.ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
}
private void readObject(final java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
initCollatorInstance();
}
}
答案 0 :(得分:3)
我认为你可以写一个包装器,