序列化 Collator 实例
Posted
技术标签:
【中文标题】序列化 Collator 实例【英文标题】:Serializing Collator instance 【发布时间】:2012-01-10 20:59:51 【问题描述】:我正在尝试序列化机构ResultView 类的一些对象,它基本上是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();
【问题讨论】:
但是请注意,如果您不存储区域设置,如果 jvm 序列化对象和 jvm 反序列化对象具有不同的默认区域设置,您将获得不同的行为。也许这就是你想要的,不过,我只是想指出这一点。 我知道这一点,我已经使用 Locale 参数实现了 CollatorWrapper,但在这里我只想展示这个问题的解决方案的本质:) 我不肯定,但我认为您可以通过直接声明私有瞬态 Collator collatorInstance = Collator.getInstance() 来避免“initCollatorInstance”的尴尬。 @LouisWasserman 是的,我也这么认为 【参考方案1】:我想你也许可以写一个包装器,它
实现比较器 实现 Serialzable(以及必要的方法,如 readObject、writeObject) 包装一个瞬态整理器 记住区域设置(如果需要)【讨论】:
以上是关于序列化 Collator 实例的主要内容,如果未能解决你的问题,请参考以下文章
python 最长的Collatz序列(Euler#14)
HuggingFace:使用自定义 data_loader 和 data_collator 从本地目录流式传输数据集