序列化与反序列化

本文通过一个快递管理系统的实例,详细介绍了Java中IO序列化和反序列化的应用。代码示例展示了如何将Express对象存储到文件,并通过反序列化恢复数据。 Dao类用于读写文件,包含添加、删除、修改和查询快递的方法。 Views类提供了用户交互界面,实现了快递员和用户的操作功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:IO序列化和反序列化的应用
序列化:就是将对象存储到文件中的过程
反序列化:就是将存储到文件数据再转换成对象的过程
废话不多说上代码

项目快递管理

Express类

package practise;

import java.io.Serializable;

public class Express implements Serializable {
    //取件码
    private int code;
    //快递公司
    private String compay;
    //快递单号
    private String expressId;

    public Express() {
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getCompay() {
        return compay;
    }

    public void setCompay(String compay) {
        this.compay = compay;
    }

    public String getExpressId() {
        return expressId;
    }

    public void setExpressId(String expressId) {
        this.expressId = expressId;
    }

    @Override
    public String toString() {
        return "Express{" +
                "code='" + code + '\'' +
                ", compay='" + compay + '\'' +
                ", expressId=" + expressId +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        Express express = (Express) o;

        return expressId != null ? expressId.equals(express.expressId) : express.expressId == null;
    }

    @Override
    public int hashCode() {
        return expressId != null ? expressId.hashCode() : 0;
    }
}

注意:和序列化有关的类必须实现Serializable标记

package practise;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class Dao  {

    private static final String PATH = "G:\\TXT.txt";
    private List<Express> list=new ArrayList<>();
    private ObjectOutputStream oos;

    public void read() throws IOException {
        File file =new File(PATH);
        if (file.exists()){
            try(ObjectInputStream obi = new ObjectInputStream(new FileInputStream(PATH))) {
                //参数是父类或父类的子类都可以
                //读取文件中list对象
                list= (List<Express>) obi.readObject();
            }catch (IOException | ClassNotFoundException e){
                e.printStackTrace();
                //如果报异常则清空list
                list = new ArrayList<>();
                throw new IOException("无法获取文件并且读取信息");
            }
        }else {
            //文件不存在 也清空list
            list = new ArrayList<>();
        }
    }

    public void write() throws IOException {
        //如果输出流未被初始化,则证明是第一次写,对比输入流进行初始化
        if (oos == null){
            oos = new ObjectOutputStream(new FileOutputStream(PATH));
        }
        //写入对象list
        oos.writeObject(list);
    }

    //根据取件码查询快递
    public Express findByCode(int code){
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).getCode()==code){
                return list.get(i);
            }
        }
        return null;
    }

    public Express findByNumber(String number){
        for (Express express : list) {
            if (number.equals(express.getExpressId())) {
                return express;
            }
        }
        return null;
    }

    //添加
    public boolean add(Express e) {
        list.add(e);
        return true;
    }
    //删除
    public boolean delete(Express e) {
        list.remove(e);
        return true;
    }
    //修改
    public boolean update(Express e,Express e1) {
        delete(e);
        list.add(e1);
        return true;
    }

    public List<Express> findAll() {
        return list;
    }
}

package practise;

import java.util.List;
import java.util.Random;
import java.util.Scanner;

public class Views {

    private Scanner scanner = new Scanner(System.in);
    //存储快递

    /**
     * 主菜单
     * @return 身份
     */
    public int menu(){
        System.out.println("请根据指令输入:(1.快递员 2.用户 0.退出)");
        String s = scanner.nextLine();
        int num=-1;
        try {
            num = Integer.parseInt(s);
        }catch (NumberFormatException e){
        }
        //只能入0-2有可能
        if (num < 0 || num > 2){
            System.out.println("请重新输入");
            return menu();
        }
        return num;
    }

    /**
     * 快递界面
     * @return 快递员功能
     */
    public int expressMenu() {
        System.out.println("===欢迎登录快递员===");
        System.out.println("请根据对应数值输入:(1.快递录入2.删除快递3.修改快递4.查看所有快递0.返回上个菜单)");
        String s = scanner.next();
        int num=-1;
        try {
             num = Integer.parseInt(s);
        }catch (NumberFormatException e){}
        if (num<0 && num>4){
            System.out.println("输入错误请重新输入");
            return expressMenu();
        }
        return num;

    }

    int code(){
        Random random=new Random();
        int num=random.nextInt(900000)+100000;
        return num ;
    }

    public Express insert() {
        Express e = new Express();
        //输入公司和快递单号
            System.out.println("请输入快递单号");
            String id = scanner.next();
            System.out.println("请输入公司");
            String expressCompany = scanner.next();
            e.setCompay(expressCompany);
            e.setExpressId(id);
            int code = code();
            e.setCode(code);
        return e;
    }


    public Express newInstall() {
        Express e = new Express();
        //输入公司和快递单号
        System.out.println("请输入新的快递单号:");
        String newId = scanner.next();
        System.out.println("请输新的入公司:");
        String expressCompany = scanner.next();

        e.setCompay(expressCompany);
        e.setExpressId(newId);
        e.setCode(code());
        return e;
    }


    private void update() {
        //输入公司和快递单号
        System.out.println("请输入要修改的快递单号");
        String s = scanner.next();
        int id=-1;
        try {
            id = Integer.parseInt(s);
        }catch (NumberFormatException n){}

    }

    int cMenu() {
        System.out.println("===欢迎登录===");
        System.out.println("请根据对应数值输入:(1.取快递)");
        String s = scanner.next();
        int num=-1;
        try {
            num = Integer.parseInt(s);
        }catch (NumberFormatException e){}
        if (num!=1){
            System.out.println("输入错误请重新输入");
            return expressMenu();
        }
        return num;
    }

    public String delete() {
        System.out.println("请输入要删除的快递单号:");
        String deleteId = scanner.next();
        return deleteId;
    }

    //输入取件码
    public int Incode() {
        int code = 0;
        System.out.println("请输入取件码:");
        String inCode = scanner.next();
        try {
            code = Integer.parseInt(inCode);
        }catch (NumberFormatException e){}

        return code;
    }
    public void printNull(){
        System.out.println("删除失败");
    }

    public void addSuccess() {
        System.out.println("添加成功");
    }
    public void addError() {
        System.out.println("添加失败");
    }

    public void pring(Express e) {
        System.out.println("快递id:"+e.getExpressId()+"公司名称:"+e.getCompay()+"验证码:"+e.getCode());
    }

    public void addError2() {
        System.out.println("添加快递重复");
    }

    public void deleteSuccess() {
        System.out.println("删除成功");
    }

    public void deleteError() {
        System.out.println("删除失败");
    }

    public String updateId() {
        System.out.println("快递id:");
        return scanner.next();
    }

    public void updateSuccess() {
        System.out.println("修改成功");
    }

    public void updateError() {
        System.out.println("修改失败");
    }

    public void updateold() {
        System.out.println("旧的对象");
    }

    public void updateNew() {
        System.out.println("新的对象");
    }

    public void findAll(List<Express> list) {
        for (int i = 0; i <list.size() ; i++) {
            if (list.get(i)!=null){
                pring(list.get(i));
            }
        }
    }

    public void takeExpressSuccess() {
        System.out.println("取件成功");
    }

    public void takeExpressError() {
        System.out.println("没有该取件码,请重新输入");
    }
}

package practise;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.List;


public class main {

    private static Dao dao=new Dao();
    private static Views view = new Views();

    public static void main(String[] args) throws IOException {
        inint();
    }


    /**
     * 初始界面
     */
    private static void inint() throws IOException {
        int role = view.menu();

            switch (role){
                case 1:
                    expressMenu();
                    //快递员界面
                    break;
                case 2:
                    cMenu();
                    //用户界面
                    break;
                case 0:
                    return;
                default :
                    break;
                }

    }
    private static void expressMenu() throws IOException {
        while (true){
            int num = view.expressMenu();
            switch (num){
                case 1:{
                    //录入
                    insert();
                    break;}
                case 2:{
                    //删除
                    delete();
                    break;}
                case 3:{
                    //修改快递
                    update();}
                    break;
                case 4: {
                //读取文件中的集合,展示文件中的全部
                   dao.read();
                    findAll();
                    break;
                }
                case 0: {
                    inint();
                    break;
                }
                default:
                    break;
        }
        }
    }

    private static void findAll() {
        List<Express> all = dao.findAll();
        view.findAll(all);
    }

    private static void update() {
        String s = view.updateId();
        if (s!=null){
            //根据快递单号查找是否有快递,有返回快递
            Express byNumber = dao.findByNumber(s);
            if (byNumber!=null){
                Express express = view.newInstall();
                boolean update = dao.update(byNumber, express);
                if (update){
                    //旧对象
                    view.updateold();
                    //输出旧对象
                    view.pring(byNumber);
                    //新的对象
                    view.updateNew();
                    //输出当前对象
                    view.pring(express);
                    //修改成功
                    view.updateSuccess();
                }else {
                    view.updateError();
                }
            }
        }
    }

    private static void delete() {
        String deleteId = view.delete();
        //查询是否存在
        Express e = dao.findByNumber(deleteId);

        if (e==null){
            //没有找到要删除值
            view.printNull();
        }else {
            boolean delete = dao.delete(e);
            if (delete){
                view.deleteSuccess();
            }else {
                view.deleteError();
            }
        }
    }
    private static void insert() throws IOException {
        Express e = view.newInstall();
        Express byNumber = dao.findByNumber(e.getExpressId());
        if (byNumber == null) {
            boolean b = dao.add(e);
            if (b){
                view.pring(e);
                view.addSuccess();
                //每像集合中插入一个数据,就对文件进行更新
                dao.write();
            }else {
                view.addError();
            }
        }else {
            view.addError2();
        }
    }

    /**
     * 顾客界面
     */
    private static void cMenu(){
        view.cMenu();
        //输入取件码
        int incode = view.Incode();
        //查找是否有取件码
        Express byCode = dao.findByCode(incode);
        if (byCode!=null){
            dao.delete(byCode);
            view.takeExpressSuccess();
        }else {
            view.takeExpressError();
            view.Incode();
        }
    }
}

运行截图
在这里插入图片描述

总结:序列化和反序列化很好理解,但实际操作需要注意一些问题。
首先要对自己序列化的对象表示明确,本项目中实际是将list集合保存至文件中,然后在文件中读取的也是list集合。
其次,是如何调用序列化和反序列化之后的list,本项目中选择了在每次插入新数据时,写入更新list,在展示全部的时候读取文件中list进行展示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值