保存 Object 数组

"你好,阿米戈!今天,我们将学习另一个有趣的主题。具体来讲,就是保存和加载(重构)对象。假设我们有一个 Cat 类:"

代码

复制代码
class Cat
{
 public String name;
 public int age;
 public int weight;
}

假设我们要添加一种便捷机制来保存到文件以及从文件加载。

我们可能会这样做:

代码

复制代码
class Cat {
    public String name;
    public int age;
    public int weight;

    public void save(PrintWriter writer) throws Exception {
        writer.println(name);
        writer.println(age);
        writer.println(weight);
        writer.flush();
    }

    public void load(BufferedReader reader) throws Exception {
        name = reader.readLine();
        age = Integer.parseInt(reader.readLine());
        weight = Integer.parseInt(reader.readLine());
    }
}

"哇!这么简单!我们只是写入每个参数的值,每行一个。加载文件时,我们以同样的顺序读取它们。这是一个完美的解决方法。"

"谢谢你,阿米戈。现在,你可以为这组类编写 save 和 load 方法:"

代码

复制代码
class Cat
{
 public String name;
 public int age;
 public int weight;
}
class Dog
{
 public String name;
 public int age;
}
class Human
{
 public Cat cat;
 public Dog dog;
}

你有一个 Human 对象,它可以包含一个 dog 和一个 cat。

"我有一个解决方法:"

代码

复制代码
class Cat {
    public String name;
    public int age;
    public int weight;

    public void save(PrintWriter writer) throws Exception {
        writer.println(name);
        writer.println(age);
        writer.println(weight);
        writer.flush();
    }

    public void load(BufferedReader reader) throws Exception {
        name = reader.readLine();
        age = Integer.parseInt(reader.readLine());
        weight = Integer.parseInt(reader.readLine());
    }
}

代码

复制代码
class Dog {
    public String name;
    public int age;

    public void save(PrintWriter writer) throws Exception {
        writer.println(name);
        writer.println(age);
        writer.flush();
    }

    public void load(BufferedReader reader) throws Exception {
        name = reader.readLine();
        age = Integer.parseInt(reader.readLine());
    }
}

代码

复制代码
public class Human {
    public Cat cat;
    public Dog dog;

    public void save(PrintWriter writer) throws Exception {
        cat.save(writer);
        dog.save(writer);
    }

    public void load(BufferedReader reader) throws Exception {
        cat.load(reader);
        dog.load(reader);
    }
}

"这个一个非常好的解决方法。但是,如果一个 human 只有 dog 而没有 cat,会发生什么呢?"

null 检查在哪里?

"我马上修改:"

代码

复制代码
public class Human {
    public Cat cat;
    public Dog dog;

    public void save(PrintWriter writer) throws Exception {
        if (cat != null)
            cat.save(writer);
        if (dog != null)
            dog.save(writer);
    }

    public void load(BufferedReader reader) throws Exception {
        cat = new Cat();
        cat.load(reader);
        dog = new Dog();
        dog.load(reader);
    }
}

"还是不太对。你有两处错误:"

1) 一个人可能没有 cat 或 dog,但在调用 load 方法时仍会创建它们

2) 如果只保存 dog,则其数据在加载时将被 cat 读取。

"那我应该怎么做?"

"我们不能跳过变量编写,否则在读取过程中会遇到问题。你需要确保在保存操作期间为 null 的变量在加载操作期间被设置为 null。下面是我的版本:"

代码

复制代码
public class Human {
    public Cat cat;
    public Dog dog;

    public void save(PrintWriter writer) throws Exception {
        String isCatPresent = cat != null ? "yes" : "no";
        writer.println(isCatPresent);
        writer.flush();

        if (cat != null)
            cat.save(writer);

        String isDogPresent = dog != null ? "yes" : "no";
        writer.println(isDogPresent);
        writer.flush();

        if (dog != null)
            dog.save(writer);
    }

    public void load(BufferedReader reader) throws Exception {

        String isCatPresent = reader.readLine();
        if (isCatPresent.equals("yes")) {
            cat = new Cat();
            cat.load(reader);
        }

        String isDogPresent = reader.readLine();
        if (isDogPresent.equals("yes")) {
            dog = new Dog();
            dog.load(reader);
        }
    }
}

"嗯,我喜欢这个解决方法。"

"是的,这个方法很好。"

相关推荐
API快乐传递者10 小时前
电商竞品分析接口实战指南:从数据采集到决策洞察的全链路方案
java·python
程序员黑豆17 小时前
Java类型推断完全指南:从var到菱形运算符,掌握使用限制与最佳实践
java·前端·ai编程
To_OC18 小时前
踩了个 TS 的坑之后,我终于把 type 和 interface 掰明白了
前端·react.js·typescript
GreenTea18 小时前
深度解读 Anthropic 多智能体报告:更强的模型 ≠ 更好的协调
前端·后端·算法
风流 少年18 小时前
Spring AI 2.0:Memory
java·后端·spring
码匠许师傅18 小时前
【C++ 面试真题】聊聊 C++ 的移动语义与右值引用
java·c++·面试
浮生望18 小时前
前端API工程化:用 Mock 数据与 Axios 配置实现独立于后端的并行开发
前端
万少19 小时前
给 DeepSeek Harness 装个"应用商店":一条命令,595 个插件随你逛
前端·javascript·后端
小席是个热心肠19 小时前
AI相关的自我学习
java·人工智能·学习
波波00719 小时前
C# 15 重磅新特性: 带标签 break 与 continue:重新定义嵌套循环控制流
服务器·前端·c#