Сериализация экземпляра Collator - PullRequest
1 голос
/ 01 декабря 2011

Я пытаюсь сериализовать некоторые объекты класса InstitutionResultView, который в основном является оболочкой для дерева гуавы 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)

...

Я обнаружил эту ошибку в базе данных ошибок Sun , которая охватывает очень похожий случай с моей, но не указывает на какое-либо разрешение. Я попытался добавить временное поле экземпляра 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();
    }
  }

1 Ответ

3 голосов
/ 01 декабря 2011

Я думаю, что вы могли бы написать оболочку, которая

  • реализует Comparator
  • реализует Serialzable (и необходимые методы, такие как readObject, writeObject)
  • упаковывает временный Collator
  • запоминает локаль (если вам это нужно)
...