2

作爲一項非常大的項目,我有一個作業(學生可以看到他們的成績,教師可以添加成績等等) 。Java無法使用比較器對包含TreeMaps的對象進行序列化

「base」類是一個包含使用的所有類(Java)的單例,如用戶數組,類(如在學校類中)和將classess和教師關聯到課程的TreeMap。

我想序列化這個基類(中央),以保存修改後的數據。問題是,我得到這個例外

java.io.NotSerializableException: liceu.Central$1 
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183) 
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547) 
at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:440) 
at java.util.TreeMap.writeObject(TreeMap.java:2265) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:606) 
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:988) 
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1495) 
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431) 
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177) 
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547) 
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508) 
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431) 
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177) 
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347) 
at liceu.Main.main(Main.java:31) 

我的課全部實現Serializable,和他們沒有瞬態或靜態字段(除了單,其中有實例變量和getInstance方法爲靜態)。

因爲這將是相當多的代碼發佈(我會冒險通過在提交之前發佈它來取消我的任務)我嘗試通過嘗試隔離錯誤來作出概念驗證。

public class Central implements Serializable 
{ 
    private ArrayList <User> users; 
    private ArrayList <Class> classess; 
    private TreeMap <Course, TreeMap <Class, Professor>> reunite; 
    private static Central instance = null; 

    private Central() 
    { 
     users = new ArrayList<>(); 
     classess = new ArrayList<>(); 
     reunite = new TreeMap<>(new Comparator<Student>(){ 
      @Override 
      public int compare(Student e1, Student e2) 
      { 
       return e1.getName().compareTo(e2.getName()); 
      } 
     }); 
    } 
} 

如果我只保留前2個ArrayLists,則序列化過程起作用。 問題出在TreeMap上。

是否可以將TreeMap類串行化? (一般情況下) 是因爲匿名比較器嗎?

這裏是與序列

public class Main 
{ 
    public static void main(String args[]) 
    { 
     Central cent = Central.getInstance(); 
     FileOutputStream fos; 
     ObjectOutputStream oos; 

     cent.addUser(new Student(3,"id","pass","name","surname")); 
     cent.addUser(new Student(3,"id2","pass","name","surname")); 
     cent.addUser(new Student(3,"id1","pass","name","surname")); 
     try 
     { 
      fos = new FileOutputStream("save.txt"); 
      oos = new ObjectOutputStream(fos); 
      oos.writeObject(cent); 
     } 

     catch(IOException e) 
     { 
      e.printStackTrace(); 
     } 
    } 
} 
+1

你有自定義比較器嗎?如果是,那麼你也必須序列化比較器。文檔:http://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html – gtgaxiola

+0

正如我看到他的自定義comperator作爲一個無縫的對象是在中央類。 – bitli

+0

@gtgaxiola不,它是一個匿名比較器。 –

回答

12

樹形圖以保持它用來比較密鑰的比較基準的主類。比較器是一個不可序列化的匿名類的實例。所以你會得到這個例外。

將匿名比較器重構爲頂級或命名的內部類,它也實現了Serializable。

2

將「implements Serializable」添加到比較器中,它應該可以解決問題。

+0

好吧,這就是我所做的... 3年前xD。 –

2

另一種方式來迫使ComparatorSerializable是將其與另外的結合投轉換爲拉姆達:

TreeMap<Integer, String> sortedMap = new TreeMap<>(
    (Comparator<Integer> & Serializable) (o1, o2) -> { 
     return o1.compareTo(o2); 
    } 
); 

這裏的解釋是: Java lambda expressions, casting, and Comparators

+0

我不認爲Java 8當時可用。 –

+1

@SilentControl,也許。但人們也一直在尋找答案。 ) – Vadzim

相關問題