TreeSet序列化問題


關於TreeSet集合進行匿名實現Comparator接口無法序列化

需求

把自定義類按照某個字段排序,並存儲到集合中,然后把類存儲到文件中。

實現

定義stu類,並繼承Serializable接口序列化

class Stu implements Serializable{
   private Integer id;
   private String name;
   private Integer age;
   public static final long serialVersionUID = 1L;

   public Stu() {
  }

   public Stu(Integer id, String name, Integer age) {
       this.id = id;
       this.name = name;
       this.age = age;
  }

   public Integer getId() {
       return id;
  }

   public void setId(Integer id) {
       this.id = id;
  }

   public String getName() {
       return name;
  }

   public void setName(String name) {
       this.name = name;
  }

   public Integer getAge() {
       return age;
  }

   public void setAge(int age) {
       this.age = age;
  }

   @Override
   public String toString() {
       return "Stu{" +
               "id=" + id +
               ", name='" + name + '\'' +
               ", age=" + age +
               '}';
  }
}

我使用TreeSet集合存儲stu類,按照age排序

    public static void main(String[] args) {
       Scanner sc=new Scanner(System.in);
       TreeSet<Stu> treeSet=new TreeSet<>(new Comparator<Stu>() {
           @Override
           public int compare(Stu o1, Stu o2) {
               return o2.getAge()-o1.getAge();//從大到小
          }
      });
       
         while (true){
           System.out.println("請輸入學生的信息:");
           String infoStu = sc.next();
           if (infoStu.equals("exit")) {
               Iterator<Stu> iterator = treeSet.iterator();
               while (iterator.hasNext()) {
                   System.out.println(iterator.next());
              }
               break;
          } else {
               String[] split = infoStu.split("#");
               Integer id = Integer.parseInt(split[0]);
               String name = split[1];
               Integer sex = Integer.parseInt(split[2]);
               treeSet.add(new Stu(id, name, sex));//把用戶輸入的信息封裝成stu對象,添加到集合中

          }
      }
     
       ObjectOutputStream bw=null;
       try {
           bw=new ObjectOutputStream(new FileOutputStream("student.txt"));
           bw.writeObject(treeSet);//使用對象流把treeSet存入
      }catch (Exception e){
           e.printStackTrace();
      }finally {
           if(bw!=null){
               try {
                   bw.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }
          }
      }

  }

結果:在把集合寫入文件中,報了序列化問題

 

出現了”沒有序列化異常“,找了很久我的Stu也現實了序列化接口,最后問題出現在了我寫的比較器上。

我實現的是匿名內部類Comparator接口,但是java.text.RuleBasedCollator實現了Comparator接口但是卻不支持Serializable接口,就是Comparator沒有實現Serializable接口導致序列化失敗。

解決辦法:

1.不適用匿名內部類Comparator接口在類中繼承Comparable接口,實現compareTo()方法

class Stu implements Serializable,Comparable{
   private Integer id;
   private String name;
   private Integer age;
   public static final long serialVersionUID = 1L;

   public Stu() {
  }

   public Stu(Integer id, String name, Integer age) {
       this.id = id;
       this.name = name;
       this.age = age;
  }

   public Integer getId() {
       return id;
  }

   public void setId(Integer id) {
       this.id = id;
  }

   public String getName() {
       return name;
  }

   public void setName(String name) {
       this.name = name;
  }

   public Integer getAge() {
       return age;
  }

   public void setAge(int age) {
       this.age = age;
  }

   @Override
   public String toString() {
       return "Stu{" +
               "id=" + id +
               ", name='" + name + '\'' +
               ", age=" + age +
               '}';
  }

   @Override
   public int compareTo(Object o) {
       Stu s=(Stu) o;
       return this.age-s.age;
  }

2.使用AarryList作為中間集合,把TreeSet添加到List集合中,在進行對象流寫入

List<Stu> list=new ArrayList<>(treeSet);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM