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