2011-12-01 50 views
1

我試圖序列化類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 java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164) at

...

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

...

我發現this bug from Sun's bug database這非常類似的事例涵蓋礦山,但它並不指向任何決議。我嘗試添加瞬態校書郎實例字段:

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

不過請注意,如果你不存儲區域設置,你會得到一個不同的行爲,如果JVM序列化對象和jvm反序列化對象具有不同的默認語言環境。也許這就是你想要的,但是,我只是想指出。 – Puce

+0

我知道這一點,我已經使用Locale參數實現了Collat​​orWrapper,但在這裏我只想顯示這個問題的解決方案的本質:) – Xaerxess

+1

我不積極,但我認爲你可以通過聲明 來避免「initCollat​​orInstance」的尷尬 專用瞬態Collat​​or collat​​orInstance = Collat​​or.getInstance() 直接。 –

回答

3

我想你也許可以編寫一個包裝,這

  • implements比較器
  • 實現Serialzable(以及必要的方法,如readObject,writeObject)
  • 包裝了一個短暫的校書郎
  • 記得區域設置(如果你需要)
+0

謝謝,我遵循你的建議,解決了我的問題! – Xaerxess