如何获取可序列化Collator实例 解决TreeMap无法序列化问题
解决方案
问题根因
Collator本身未实现Serializable接口,直接作为排序规则传入TreeMap时,TreeMap序列化会因为比较器不可序列化抛出异常。
可落地实现方案
- 方案1:封装可序列化的Collator包装类
自定义实现同时继承Serializable和Comparator接口的包装类,内部持有Collator实例,序列化时仅存储Collator的区域设置、强度、分解模式等核心配置,反序列化时根据配置重新构建Collator实例。
示例代码:
import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.text.Collator; import java.util.Comparator; import java.util.Locale; public class SerializableCollator implements Comparator<String>, Serializable { private transient Collator collator; private final Locale locale; private final int strength; private final int decomposition; public SerializableCollator(Locale locale) { this.locale = locale; this.collator = Collator.getInstance(locale); this.strength = collator.getStrength(); this.decomposition = collator.getDecomposition(); } // 支持自定义调整Collator参数后同步到配置项 public void setStrength(int strength) { this.collator.setStrength(strength); } public void setDecomposition(int decomposition) { this.collator.setDecomposition(decomposition); } // 自定义序列化逻辑,仅存储核心配置参数 private void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); } // 反序列化时根据存储的配置重新构建Collator实例 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); collator = Collator.getInstance(locale); collator.setStrength(strength); collator.setDecomposition(decomposition); } @Override public int compare(String o1, String o2) { return collator.compare(o1, o2); } }
使用时直接将SerializableCollator实例作为比较器传入TreeMap即可,无需修改原有排序逻辑。
- 方案2:自定义TreeMap序列化逻辑
如果不想修改原有比较器实现,可以继承TreeMap重写序列化、反序列化方法,序列化时仅存储Collator的配置参数,反序列化时重新生成Collator实例赋值给父类的comparator属性。
注意事项
- 不要尝试直接序列化
Collator实例本身,不同JDK版本、不同运行环境的Collator实现存在差异,直接序列化会出现反序列化不兼容问题 - 存储Collator配置时要覆盖所有自定义修改的参数,避免反序列化后排序规则和原规则不一致
内容的提问来源于stack exchange,提问作者PeraltaBoi
相关产品推荐
相关产品推荐

