序列化一组对象,并实现排序和反序列换存取
序列化一组对象,并实现存取与反序列化(treeSet方法)
要求:使用一个用户类自定义属性并创建10个对象,按照用户年龄升序排序,若年龄相同则按姓名的字符自然次序排序,然后把10个对象序列化并写入d盘中,并通过实现反序列化循环输出。
使用treeset方法存储对象时,由于该集合容器底层是二叉树,所以在存储自定义对象时一定要
提供比较策略
可以根据自己的需要编写 内部比较策略或外部比较策略 在外部比较策略不需要进行序列化时可以将外部比较策略写成匿名内部类形式,但该要求有序列化存储,所以不再使用匿名内部类方式实现比较策略的提供
在此只实现内部比较策略和外部比较策略(实际应用时,提供一种形式的比较策略即可)。
自定义Worker类(同时实现了内部比较策略——通过实现Comparable接口)
import java.io.Serializable;
public class Worker implements Serializable,Comparable<Worker>{
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
private int age;
private int salary;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public Worker() {
super();
}
public Worker(String name, int age, int salary) {
super();
this.name = name;
this.age = age;
this.salary = salary;
}
@Override
public String toString() {
return "Worker [name=" + name + ", age=" + age + ", salary=" + salary + "]";
}
@Override
//内部比较策略,通过实现Comparable接口实现comparaTo方法实现自定义比较策略
public int compareTo(Worker o) {
if(this.getAge()!=o.getAge()) {
return this.getAge()-o.getAge();
}else {
return this.getName().compareTo(o.getName());
}
}
}
自定义类内实现了自定义比较策略
测试类代码1(使用内部比较策略,无外部比较策略)
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Iterator;
import java.util.TreeSet;
public class WorkerTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
TreeSet<Worker> ts = new TreeSet<Worker>();
Worker w1 = new Worker("abcdefghij", 19, 6000);
Worker w2 = new Worker("bcdefghij", 18, 6000);
Worker w3 = new Worker("cdefghij", 17, 6000);
Worker w4 = new Worker("defghij", 16, 6000);
Worker w5 = new Worker("efghij", 15, 6000);
Worker w6 = new Worker("fghij", 14, 6000);
Worker w7 = new Worker("ghij", 13, 6000);
Worker w8 = new Worker("hij", 12, 6000);
Worker w9 = new Worker("ij", 11, 6000);
Worker w10 = new Worker("j", 10, 6000);
ts.add(w10);
ts.add(w9);
ts.add(w8);
ts.add(w7);
ts.add(w6);
ts.add(w5);
ts.add(w4);
ts.add(w3);
ts.add(w2);
ts.add(w1);
System.out.println(ts.toString());
File file = new File("G:\\javaFileTest\\123.obj");
boolean r = false;
if (!file.exists()) {
r = file.createNewFile();
}
if (r) {
System.out.println("文件创建成功!");
} else {
System.out.println("文件已存在!");
}
FileOutputStream fot = new FileOutputStream(file);
//序列化到文件
ObjectOutputStream oos = new ObjectOutputStream(fot);
oos.writeObject(ts);
System.out.println("序列化到文件成功");
ObjectInputStream ois=new ObjectInputStream(new FileInputStream(file));
@SuppressWarnings("unchecked")
//反序列化到指定集合
TreeSet<Worker> tsNew=(TreeSet<Worker>)ois.readObject();
System.out.println("反序列化依次输出:");
Iterator<Worker> it=ts.iterator();
while(it.hasNext()) {
Worker item=it.next();
System.out.println(item.toString());
}
System.out.println("反序列化输出:");
System.out.println(tsNew.toString());
fot.close();
oos.close();
ois.close();
}
}
运行效果:
由于序列化写入的数据并不对应现实中的语言,所以存储的信息是乱码的形式,但这并不影响程序的读取。
文件内容:
测试代码二:使用外部比较策略,并将比较策略实现序列化接口
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
public class WorkerTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//实例化外部比较策略
Diycomparator diycomparator=new Diycomparator();
TreeSet<Worker> ts = new TreeSet<Worker>(diycomparator);//使用外部比较策略
Worker w1 = new Worker("abcdefghij", 19, 6000);
Worker w2 = new Worker("bcdefghij", 18, 6000);
Worker w3 = new Worker("cdefghij", 17, 6000);
Worker w4 = new Worker("defghij", 16, 6000);
Worker w5 = new Worker("efghij", 15, 6000);
Worker w6 = new Worker("fghij", 14, 6000);
Worker w7 = new Worker("ghij", 13, 6000);
Worker w8 = new Worker("hij", 12, 6000);
Worker w9 = new Worker("ij", 11, 6000);
Worker w10 = new Worker("j", 10, 6000);
ts.add(w10);
ts.add(w9);
ts.add(w8);
ts.add(w7);
ts.add(w6);
ts.add(w5);
ts.add(w4);
ts.add(w3);
ts.add(w2);
ts.add(w1);
System.out.println(ts.toString());
File file = new File("G:\\javaFileTest\\123.obj");
boolean r = false;
if (!file.exists()) {
r = file.createNewFile();
}
if (r) {
System.out.println("文件创建成功!");
} else {
System.out.println("文件已存在!");
}
FileOutputStream fot = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fot);
oos.writeObject(ts);
System.out.println("序列化到文件成功");
ObjectInputStream ois=new ObjectInputStream(new FileInputStream(file));
@SuppressWarnings("unchecked")
TreeSet<Worker> tsNew=(TreeSet<Worker>)ois.readObject();
System.out.println("反序列化依次输出:");
Iterator<Worker> it=ts.iterator();
while(it.hasNext()) {
Worker item=it.next();
System.out.println(item.toString());
}
System.out.println("反序列化输出:");
System.out.println(tsNew.toString());
fot.close();
oos.close();
ois.close();
}
}
//外部计较策略,重新定义新类实现Comparator接口,实现自定义比较策略
class Diycomparator implements Comparator<Worker>,Serializable{
/**
* 序列化一定要提供固定版本号
*/
private static final long serialVersionUID = 1L;
@Override
public int compare(Worker o1, Worker o2) {
if(o1.getAge()!=o2.getAge()) {
return o1.getAge()-o2.getAge();
}else {
return o1.getName().compareTo(o2.getName());
}
}
}
由於比較策略相同,控制臺效果和文件效果相同,這裏不再展示。
由於存入treeSet時,其底層是二叉樹,程序裏提供的比較策略又是升序,所以使用迭代器輸出時便是按指定關鍵字(年齡、名字自然順序)升序輸出
若反序列化对象不在同一包内,其反序列化出来的内容包含包名,切记用于接收的对象和反序列化内容的包名相同