简体   繁体   English

在Java中序列化具有多对多关系的两个对象

[英]Serialize two objects with many-to-many relationship in java

I have class "Book" and class "Author" in Java.There is many-to-many relationship between Book and Author. 我在Java中有“书籍”类和“作者”类。书籍与作者之间存在多对多关系。

Book Class : 书类:

public class Book
{
    int ISPN;
    String title;
    String description;
    int pageCount;
    public ArrayList<Author> Authors;
}

Author Class : 作者类别:

public class Author 
{
    int authorID;
    String firstName;
    String lastName;
    ArrayList<Book> books;
}

I want to serialize an object of Book or Author, but there will be an infinite recursion, as every Book has a list of his associated authors, who have their associated books, etc to infinity. 我想序列化Book或Author的对象,但是会有无限递归,因为每本Book都有其关联作者的列表,他们的关联书籍等都无限。 So how to handle situations like this ? 那么如何处理这种情况呢?

Sorry for my bad English. 对不起,我的英语不好。

As far as you have many-to-many relationship you need to have some storage in order to store all data (something like database). 就您与多对多的关系而言,您需要一些存储空间才能存储所有数据(例如数据库)。 And the best approach IMHO is make you lists transient and restore items from this storage when you are restoring your serialisable. 恕我直言,最好的方法是让您在恢复序列化文件时列出此存储的暂态和恢复项目。 If it is really database in your case you can use some in-memory cache in order to make it faster. 如果您的情况确实是数据库,则可以使用一些内存中的缓存以使其更快。

[EDIT]: [编辑]:

Here is alternative implementation with storage: 这是存储的替代实现:

Storage.java : Storage.java

public class Storage implements Serializable {
    private final HashMap<Integer, Book> books;
    private final HashMap<Integer, Author> authors;

    public Storage() {
        books = new HashMap<>();
        authors = new HashMap<>();
    }

    public void addBook(Book book) {
        books.put(book.ISPN, book);
    }

    public void removeBook(Book book) {
        books.remove(book.ISPN);
    }

    public void addAuthor(Author author) {
        authors.put(author.authorID, author);
    }

    public void removeAuthor(Author author) {
        authors.remove(author.authorID);
    }

    public Author getAuthor(Integer authorId) {
        return authors.get(authorId);
    }

    public Book getBook(Integer bookId) {
        return books.get(bookId);
    }
}

Book.java : Book.java

public class Book implements Serializable {
    int ISPN;
    String title;
    String description;
    int pageCount;
    ArrayList<Integer> AuthorIds;
    Storage storage;

    public Book(Storage storage) {
        this.storage = storage;
    }

    public void addAuthor(Author author) {
        storage.addAuthor(author);
        AuthorIds.add(author.authorID);
    }

    public List<Author> createAuthorsList() {
        List<Author> authorList = new ArrayList<>();
        for (Integer authorId : AuthorIds) {
            authorList.add(storage.getAuthor(authorId));
        }
        return authorList;
    }
}

Author.java : Author.java

public class Author {
    int authorID;
    String firstName;
    String lastName;
    ArrayList<Integer> bookIds;
    Storage storage;

    public Author(Storage storage) {
        this.storage = storage;
    }

    public void addBook(Book book) {
        storage.addBook(book);
        bookIds.add(book.ISPN);
    }

    public List<Book> createBooksList() {
        List<Book> bookList = new ArrayList<>();
        for (Integer bookId : bookIds) {
            bookList.add(storage.getBook(bookId));
        }
        return bookList;
    }
}

The only one (but big) disadvantage of using this implementation, that after deserialisation you will have multiple instances of Storage class with same data. 使用此实现的唯一(但很大)缺点是,在反序列化之后,您将拥有具有相同数据的多个Storage类实例。 It order to optimize this I would suggest you to make storage entries as transient members and serialize them separately. 为了优化此功能,我建议您将存储条目作为临时成员进行创建,并分别对其进行序列化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM