图书管理系统

我们用一个列表存放书籍信息。

private static List<Book> LIST = new ArrayList<>();

基本的 增、删、改、查 功能。

public static void main(String[] args) {
        readData();
        Scanner scanner = new Scanner(System.in);
        while(true) {
            System.out.println("================ 图书管理系统 ================");
            System.out.println("1.插入信息");
            System.out.println("2.修改信息");
            System.out.println("3.查询图书列表");
            System.out.println("4.删除图书");
            System.out.println("(按任意键退出系统)");
            String str = scanner.nextLine();
            switch (str){
                case "1":
                    insertBook(scanner);
                    break;
                case "2":
                    modifyBook(scanner);
                    break;
                case "3":
                    showBooks();
                    break;
                case "4":
                    deleteBook(scanner);
                    break;
                default:
                    saveData();
                    scanner.close();
                    return;
            }
        }
    }

一本图书包含:图书名称、作者名、价格。下面这种构造函数的写法是为了后面能够更方便地使用链式写法。

private static class Book implements Serializable{
        String name;
        String author;
        transient double price;

        public Book name(String name){
            this.name = name;
            return this;
        }

        public Book author(String author){
            this.author = author;
            return this;
        }

        public Book price(double price){
            this.price = price;
            return this;
        }

        @Override
        public String toString() {
            return "书籍{" +
                    "名称='" + name + '\'' +
                    ", 作者='" + author + '\'' +
                    ", 价格=" + price +
                    '}';
        }
    }

implements Serializable 的目的是在网络传输过程中将类对象转换为字符序列,这些字符序列可以用来重建对象。

  • 持久存储,将对象的状态保存在存储媒体中以便可以在以后重新创建出完全相同的副本。
  • 按值封送,尤其是在分布式系统中。如果对象标记为 Serializable,则该对象将被自动序列化,并从一个应用程序域传输至另一个应用程序域,然后进行反序列化,从而在第二个应用程序域中产生出该对象的一个精确副本。

如果用 transient 声明一个实例变量,当对象存储时它的值不需要维持,换句话来说就是,用 transient 关键字标记的成员变量不参与序列化过程。transient 关键字只能修饰变量,而不能修饰方法和类。

  • transient 是 Java 语言的关键字,用来表示一个成员变量不是该对象序列化的一部分,当一个对象被序列化的时候,transient 型变量的值不包括在序列化的结果中,而非 transient 型的变量是被包括进去的,注意 static 修饰的静态变量天然就是不可序列化的。
  • 一旦变量被 transient 修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法被访问,本地变量是不能被 transient 关键字修饰的,变量如果是用户自定义类变量,则该类需要实现 Serializable 接口。

添加书籍

private static void insertBook(Scanner scanner){
        Book book = new Book()
                .name(scanner.nextLine())
                .author(scanner.nextLine())
                .price(scanner.nextDouble());
        LIST.add(book);
        scanner.nextLine();
    }

删除书籍

private static void deleteBook(Scanner scanner){
        int i = 0;
        for (Book book: LIST){
            System.out.println(i + "." + book);
        }
        int index = scanner.nextInt();
        if (index >= LIST.size())
            System.out.println("错误的序号");
        else
            LIST.remove(i);
        scanner.nextLine();
    }

查看书籍

private static void showBooks(){
        LIST.forEach(System.out::println);
    }

修改书籍

private static void modifyBook(Scanner scanner){
        int i = 0;
        for(Book book: LIST) System.out.println(i+"."+book);
        int index = scanner.nextInt();
        scanner.nextLine();
        if(index >= LIST.size())
            System.out.println("错误的序号");
        else {
            LIST
                    .get(index)
                    .name(scanner.nextLine())
                    .author(scanner.nextLine())
                    .price(scanner.nextDouble());
        }
        scanner.nextLine();
    }

持久化(读)

@SuppressWarnings("unchecked")
private static void readData(){
    File file = new File("data");
    if(file.exists()) {
        try(ObjectInputStream inputStream = new ObjectInputStream((new FileInputStream("data")))){
            LIST = (List<Book>) inputStream.readObject();
        } catch(IOException | ClassNotFoundException e){
            e.printStackTrace();
        }
    } else{
        LIST = new ArrayList<>();
    }
}

持久化(存)

private static void saveData(){
    try(ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("data"))){
        outputStream.writeObject(LIST);
        outputStream.flush();
    } catch(IOException e){
        e.printStackTrace();
    }
}

持久化后,直接可以读取到存在 data 中的数据。

java删除第一张图片_JavaSE