Book repository for storing books that are accessed by ISBN I want to implement a book repository using a map where books can be added, removed and updated. Books in this repository should be accessed by their ISBN which is an object property. The books should not be edited from the outside of the repository, because if a book’s ISBN is changed from the outside, the ISBN used as key is out of sync with the ISBN of the book.

Another option is to use a list, so I don’t have a key that can be out of sync.

I came up with the following solution.

Book:

public class Book {
    private String isbn;
    private String title;
    private String author;
    private double price;

    public Book(String isbn, String title, String author, double price) {
        this.isbn = isbn;
        this.title = title;
        this.author = author;
        this.price = price;
    }

    public Book(Book book) {
        this.isbn = book.isbn;
        this.title = book.title;
        this.author = book.author;
        this.price = book.price;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Book other = (Book) obj;
        if (isbn == null) {
            if (other.isbn != null)
                return false;
        } else if (!isbn.equals(other.isbn))
            return false;
        return true;
    }

    // getters, setters and hashcode omitted
}


BookRepository:

public class BookRepository {
    private Map&lt;String, Book&gt; books;

    public BookRepository() {
        books = new HashMap&lt;String, Book&gt;();
    }

    public List&lt;Book&gt; getAllBooks() {
        return new ArrayList&lt;Book&gt;(books.values());
    }

    public Book getBook(String isbn) {
        if (books.containsKey(isbn))
            return new Book(books.get(isbn));

        return null;
    }

    public boolean addBook(Book book) {
        Book copy = new Book(book);

        if (!books.containsKey(copy.getIsbn()))
            return books.put(copy.getIsbn(), copy) == null;

        return false;
    }

    public boolean deleteBook(String isbn) {
        return books.remove(isbn) != null;
    }

    public boolean updateBook(Book book) {
        Book copy = new Book(book);

        if (books.containsKey(copy.getIsbn()))
            return books.put(copy.getIsbn(), copy) != null;

        return false;
    }
}
Your code is nice and the only advice I can give you is this: getAllBooks() may be improved from linear to constant time.

Consider

public boolean addBook(Book book) {
    Book copy = new Book(book);

    if (!books.containsKey(copy.getIsbn())) {
        this.list.add(book);
        return books.put(copy.getIsbn(), copy) == null;
    }

    return false;
}

public List&lt;Book&gt; getAllBooks() {
    return Collections.unmodifiableList(this.list);
}


Hope that helps.