java - 序列化 LinkedList<Object> 的语法

标签 java serialization linked-list

作为练习,我将创建一个 Books 列表作为 LinkedList,并使用 Comparator 接口(interface)按作者或书名对它们进行排序。 首先,我创建了一类书籍并确保它将按照我希望的方式打印到屏幕上:

class Book {
    String title;
    String author;
    public Book(String t, String a){
        title = t;
        author = a;
    }
    public String toString(){
        return title + "\t" + author;
    }
}

接下来,我创建了一个接受 Object Book 的 LinkedList:

LinkedList<Book> bookList = new LinkedList<>();

创建了一个实现 Comparator 的类,它根据标题/作者进行排序,并将它们显示在我的主框架内的 JTextArea 上。所有这些都运行良好,但有一个明显的错误...我无法保存文件!

我尝试了一个实现 Serializable 的类,该类将 LinkedList 作为参数,然后写入一个 .obj 文件。当我加载它时,它失败了。它会创建文件,但我通常会收到 NotSerializableException。我还尝试将文件另存为 .ser,因为有人告诉我这样可以更容易地保存它,但这在加载时也失败了。

有谁知道使用 BufferedReader 序列化 LinkedList 的好方法吗?或者还有另一种方法吗? 提前感谢您花时间阅读这个问题,也感谢您提供的任何建议、评论或答案。谢谢,伙计们。

添加: 这是完整的代码:

import javax.swing.*;
import java.util.*;
import java.awt.event.*;
import java.awt.*;
import java.io.*;

public class Check {

    BookCompare bc = new BookCompare();
    LinkedList<Book> bookList = new LinkedList<>();
    JFrame frame;
    JPanel northPanel, centerPanel, southPanel;
    JButton addBook, saveBook, loadBook;
    JTextField authorField, titleField;
    JTextArea displayBook;

    public static void main(String[] args) {
        new Check().buildGui();
    }

    private void buildGui() {
        frame = new JFrame("Book List");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        northPanel = new JPanel();
        centerPanel = new JPanel();
        southPanel = new JPanel();

        addBook = new JButton("Add Book");
        addBook.addActionListener(new AddButton());
        saveBook = new JButton("Save List");
        saveBook.addActionListener(new SaveButton());
        loadBook = new JButton("Load List");
        loadBook.addActionListener(new LoadButton());

        JLabel authorL = new JLabel("Author:");
        authorField = new JTextField(10);
        JLabel titleL = new JLabel("Title:");
        titleField = new JTextField(10);

        displayBook = new JTextArea(20,40);
        displayBook.setEditable(false);
        JScrollPane scroll = new JScrollPane(displayBook);
        scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

        northPanel.add(titleL);
        northPanel.add(titleField);
        northPanel.add(authorL);
        northPanel.add(authorField);
        centerPanel.add(scroll);
        southPanel.add(addBook);
        southPanel.add(saveBook);
        southPanel.add(loadBook);

        frame.getContentPane().add(BorderLayout.NORTH,northPanel);
        frame.getContentPane().add(BorderLayout.CENTER,centerPanel);
        frame.getContentPane().add(BorderLayout.SOUTH,southPanel);

        frame.setVisible(true);
        frame.setSize(500, 500);
        frame.setResizable(false);
        frame.setLocation(375, 50);
    }

    class AddButton implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            addToList();
            sortAndDisplay();
            readyNext();
        }
    }

    private void addToList() {
        String newTitle = titleField.getText();
        String newAuthor = authorField.getText();
        bookList.add(new Book(newTitle, newAuthor));
    }

    private void sortAndDisplay() {
        displayBook.setText(null);
        Collections.sort(bookList,bc);
        for(int i = 0; i < bookList.size(); i++){
            displayBook.append(bookList.get(i).toString());
        }
    }

    private void readyNext() {
        authorField.setText(null);
        titleField.setText(null);
        titleField.requestFocus();
    }

    class SaveButton implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            try {
                ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream("save.ser"));
                oo.writeObject(bookList);
                oo.close();
            } catch (IOException ioe){}
        }
    }

    class LoadButton implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            try {
                ObjectInputStream oi = new ObjectInputStream(new FileInputStream("save.ser"));
                Object booksIn = oi.readObject();
                Book inBook = (Book)booksIn;
                bookList.add(inBook);
                sortAndDisplay();
                oi.close();
            } catch (Exception exc){}
        }
    }

    class BookCompare implements Comparator<Book> {
        public int compare(Book one, Book two) {
            return one.title.compareTo(two.title);
        }
    }

    class Book implements Serializable{
        String title;
        String author;
        public Book(String t, String a) {
            title = t;
            author = a;
        }
        public String toString(){
            return title + "\t" + author + "\n";
        }
    }
}

最佳答案

像这样让你的 Book 类 Serializable

class Book implements Serializable{
  String title;
  String author;
  public Book(String t, String a){
     title = t;
     author = a;
  }
  public String toString(){
     return title + "\t" + author;
  }
}

序列化接口(interface)没有方法或字段,仅用于标识可序列化的语义。因此您无需实现任何方法,只需声明即可。
根据 java docs

Serializability of a class is enabled by the class implementing the java.io.Serializable interface. Classes that do not implement this interface will not have any of their state serialized or deserialized. All subtypes of a serializable class are themselves serializable. The serialization interface has no methods or fields and serves only to identify the semantics of being serializable.

更新以解决当前问题
您错误地实现了反序列化过程。这是正确的实现。试试这个您会得到想要的结果。

class LoadButton implements ActionListener {
    public void actionPerformed(ActionEvent e) {
        try {
            ObjectInputStream oi = new ObjectInputStream(new FileInputStream("save.ser"));
            Object booksIn = oi.readObject();
            bookList = (LinkedList<Book>)booksIn;
            sortAndDisplay();
            oi.close();
        } catch (Exception exc){}
    }
 }

关于java - 序列化 LinkedList<Object> 的语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18111717/

相关文章:

c# - JavaScriptSerializer.Deserialize - 如何更改字段名称

c# - 我将默认 JsonSerializer 设置为 Utf8Json

java - 如何在现有键处将唯一值添加到 HashMap

java - AWS 简单电子邮件服务 - Java 接收 Lambda 和 STOP_RULE

java - Spring data jpa SELECT ... FOR UPDATE 查询不适用于@query

java - 如何不序列化继承的非 transient 字段?

c++ - 将项目添加到双向链表的后面时遇到问题

java - Eclipse 未找到某些声明的方法(在 Vaadin 库中)

java - Spring Java 配置中的别名定义

c++ - 为什么不能在不创建节点作为指针的情况下创建链表?