序列(持久)化对象、对象输出流(ObjectOutputStream)、对象输入流(ObjectInputStream)、使用集合序列化对象 Java第十八天(一)

序列化流(对象流Serializable)

  定义:将对象以流的形式存储在硬盘上或者数据库中的过程就是写序列化流。
  反序列化:从硬盘或数据库中读取的过程就是反序列化。

 对象输出流(ObjectOutputStream)

  定义:ObjectOutputStream将Java对象的原始数据类型和图形写入OutputStream。(序列化过程)
如果想要序列化某个对象,那么这个对象要实现Serializable接口。
写入到文本文件中的字符我们读不懂,也不需要读懂。

  常用构造器

ObjectOutputStream(OutputStream out) 
创建一个写入指定的OutputStream的ObjectOutputStream。 (持久化对象)

  持久化对象方法

void 				writeObject(Object obj) 
将指定的对象写入ObjectOutputStream。  

  序列化(持久化对象)用法(将对象存储到硬盘或数据库中)

 Student类 

/**
 * Student类
 */
public class Student implements Serializable{
	//定义学生类成员变量
	private Integer id;
	private String name;
	private Integer 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(Integer age) {
		this.age = age;
	}
	//生成相应的构造器
	public Student(Integer id, String name, Integer age) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}

	//重写toString方法
	@Override
	public String toString() {
		return "Student [学号=" + id + ", 姓名=" + name + ", 年龄=" + age + "]"+" ";
	}
}

 序列化(持久化对象)类 

public class SerialDemo {

	public static void main(String[] args) {
		writeObject();
	}
	public static void writeObject() {
//		创建序列化对象输出流对象
		ObjectOutputStream oos = null;
		try {
//			创建输出流对象
			oos = new ObjectOutputStream(new FileOutputStream("Test1.txt"));
			Student s = new Student(15,"张三",20);
			oos.writeObject(s);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try {
				if(oos != null) {
					oos.close();
				}
			} catch (IOException e) {
			}
		}
	}
}

 对象输入流(ObjectInputStream)

  ObjectInputStream对先前使用ObjectOutputStream编写的基本数据和对象进行反序列化。(反序列化过程)

  常用构造器

ObjectInputStream(InputStream in) 
创建从指定的InputStream读取的ObjectInputStream。 

  读取对象方法

Object 				readObject() 
从ObjectInputStream读取一个对象。  

  反序列化(读取对象)用法(从硬盘或数据库中读取对象)

注意:每当持续化一个对象时,Java同时都会赋予一个serialVersionUID(序列化版本号)。当写入与读取发生UID不匹配时就会报错,所以我们需要自动生成一个serialVersionUID,这样即使对象类发生了变化也不会影响反序列化。

自动生成serialVersion(序列化版本号)方法:
在这里插入图片描述

 Student类 

/**
 * Student类
 */
public class Student implements Serializable{
	/**
	 * 自动给类一个序列化版本号,即使类发生了变化也不会影响反序列化
	 */
	private static final long serialVersionUID = -7068496636765082214L;
	//定义学生类成员变量
	private Integer id;
	private String name;
	private Integer 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(Integer age) {
		this.age = age;
	}
	//生成相应的构造器
	public Student(Integer id, String name, Integer age) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}

	//重写toString方法
	@Override
	public String toString() {
		return "Student [学号=" + id + ", 姓名=" + name + ", 年龄=" + age + "]"+" ";
	}
}

 反序列化类 

public class SerialDemo {
	public static void main(String[] args) {
		readObject();
	}
	public static void readObject() {
//		创建对象输入流对象
		ObjectInputStream ois = null;
		try {
//			创建字节输入流对象
			ois = new ObjectInputStream(new FileInputStream("Test1.txt"));
//			读取到Object类型的对象,并将其强转为Student类型
			Student s = (Student)ois.readObject();
			System.out.println(s);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}catch (ClassNotFoundException e) {
			e.printStackTrace();
		}finally {
			try {
				if(ois != null) {
					ois.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

 集合序列化

  当读取到最后一个已持久对象再向后读取时,返回值并不是null,而是直接报EOFException。EOF表示读到了文件尾,并且后面已经没有内容可以读了。
  由于ArrayList已经实现了Serializable接口,所以我们可以直接使用ArrayList进行写入。

 Student类 

/**
 * Student类
 */
public class Student implements Serializable{
	/**
	 * 自动给类一个序列化版本号,即使类发生了变化也不会影响反序列化
	 */
	private static final long serialVersionUID = -7068496636765082214L;
	//定义学生类成员变量
	private Integer id;
	private String name;
	private Integer 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(Integer age) {
		this.age = age;
	}
	//生成相应的构造器
	public Student(Integer id, String name, Integer age) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}

	//重写toString方法
	@Override
	public String toString() {
		return "Student [学号=" + id + ", 姓名=" + name + ", 年龄=" + age + "]"+" ";
	}

 使用数组序列化 反序列化对象 

public class SerialArrayDemo {

	public static void main(String[] args) {
//		先执行写入
		writeObject();
//		写入执行完毕后再执行读取
		readObject();
	}
	public static void writeObject() {
//		创建序列化对象输出流对象
		ObjectOutputStream oos = null;
		try {
//			创建输出流对象
			oos = new ObjectOutputStream(new FileOutputStream("Test1.txt"));
//			使用List也可以用来存储对象
			List<Student> stuArray = new ArrayList<Student>();
			stuArray.add(new Student(23,"张三",20));
			stuArray.add(new Student(17,"李四",25));
			stuArray.add(new Student(45,"王五",29));
			stuArray.add(new Student(21,"韩六",30));
			oos.writeObject(stuArray);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try {
				if(oos != null) {
					oos.close();
				}
			} catch (IOException e) {
			}
		}
	}
	public static void readObject() {
//		创建对象输入流对象
		ObjectInputStream ois = null;
		try {
//			创建字节输入流对象
			ois = new ObjectInputStream(new FileInputStream("Test1.txt"));
//			读取到Object类型的对象,并将其强转为Student类型
			ArrayList<Student> stuArray = (ArrayList<Student>)ois.readObject();
			
//			使用外置比较器将序列集合排序
//			stuArray.sort(new StuComparator());
			
//			使用增强for循环打印
			for(Student s:stuArray){
				System.out.println(s);
			}
			
//			或者直接打印ArrayList
			System.out.println(stuArray);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}catch (ClassNotFoundException e) {
			e.printStackTrace();
		}finally {
			try {
				if(ois != null) {
					ois.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

 外置比较器类 

public class StuComparator implements Comparator<Student> {

	@Override
	public int compare(Student stu1, Student stu2) {
			//先比较学号
			int val = stu1.getId() - stu2.getId();
			if(val == 0) {
				//若学号相同比较年龄
				val = stu1.getAge() - stu2.getAge();
				if(val == 0) {
					//判断两个对象的姓名是否为空
					if(stu1.getName() != null && stu2.getName() != null) {
						//若学号、年龄都相同,比较姓名
						val = stu1.getName().compareTo(stu2.getName());
					}
				}
			}
			return val;
		}
	}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值