序列化Collat​​or实例

时间:2011-12-01 17:59:58

标签: java serialization collation guava

我正在尝试序列化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.RuleBasedCollat​​or at   java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164)     在

     

...

     

com.google.common.collect.TreeMultimap.writeObject(TreeMultimap.java:180)

     

...

我发现this bug from Sun's bug database涵盖了与我非常相似的案例,但它没有指出任何解决方案。我尝试添加瞬态Collat​​or实例字段:

  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();
    }
  }

1 个答案:

答案 0 :(得分:3)

我认为你可以写一个包装器,

  • 实现Comparator
  • 实现Serialzable(以及必要的方法,如readObject,writeObject)
  • 包装瞬态Collat​​or
  • 会记住区域设置(如果需要)