返回符合Java所有以下标准的所有书籍的标题?

时间:2018-01-17 19:49:28

标签: java

我希望实现以下要求。

方法Set<String> suggestBooks(Reader reader)应返回符合以下所有条件的所有图书的标题:

 1. Have a rating of four or higher
 2. Belong to one of the reader's favourite genres
 3. Belong to favourite books' list of at least one different reader of the same age

几乎我开发了所有东西,但如何做出以上决定?

Author.java

public class Author {

    private String firstName;
    private String lastName;

    public Author(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}

Book.java

public class Book {

    private final Author author;

    private final String title;

    private final String isbn;

    private final Genre genre;

    private int rating;

    public Book(Author author, String title, String isbn, Genre genre) {
        this.author = author;
        this.title = title;
        this.isbn = isbn;
        this.genre = genre;
    }

    public Book(Author author, String title, String isbn, Genre genre, int rating) {
        validate(rating);
        this.author = author;
        this.title = title;
        this.isbn = isbn;
        this.genre = genre;
        this.rating = rating;
    }

    private void validate(int rating) {
        if (rating > 5 || rating < 1) {
            throw new IllegalArgumentException();
        }
    }

    public Author getAuthor() {
        return author;
    }

    public String getTitle() {
        return title;
    }

    public String getIsbn() {
        return isbn;
    }

    public int getRating() {
        return rating;
    }

    public void setRating(int rating) {
        validate(rating);
        this.rating = rating;
    }

    public Genre getGenre() {
        return genre;
    }

    @Override
    public int hashCode() {
        int result = author != null ? author.hashCode() : 0;
        result = 31 * result + (title != null ? title.hashCode() : 0);
        result = 31 * result + (isbn != null ? isbn.hashCode() : 0);
        result = 31 * result + (genre != null ? genre.hashCode() : 0);
        result = 31 * result + rating;
        return result;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Book book = (Book) o;

        if (rating != book.rating) return false;
        if (author != null ? !author.equals(book.author) : book.author != null) return false;
        if (title != null ? !title.equals(book.title) : book.title != null) return false;
        if (isbn != null ? !isbn.equals(book.isbn) : book.isbn != null) return false;
        return genre == book.genre;
    }
}

Genre.java

public enum Genre {

    FICTION,
    HORROR,
    COMEDY,
    DRAMA,
    NON_FICTION,
    REALISTIC,
    ROMANTIC,
    TECH,
    TRAGEDY,
    FANTASY
}

Reader.java

public class Reader {

    private final Set<Book> favouriteBooks = Sets.newHashSet();
    private final Set<Genre> favouriteGenres = Sets.newHashSet();
    private int age;

    public Reader(int age) {
        this.age = age;
    }

    public void addToFavourites(Book book) {
        favouriteBooks.add(book);
    }

    public void addToFavourites(Genre genre) {
        favouriteGenres.add(genre);
    }

    public void removeFromFavourites(Book book) {
        favouriteBooks.remove(book);
    }

    public void removeFromFavourites(Genre genre) {
        favouriteGenres.remove(genre);
    }

    public int getAge() {
        return age;
    }

    public Set<Book> getFavouriteBooks() {
        return Sets.newHashSet(favouriteBooks);
    }

    public Set<Genre> getFavouriteGenres() {
        return Sets.newHashSet(favouriteGenres);
    }

    @Override
    public int hashCode() {
        int result = favouriteBooks.hashCode();
        result = 31 * result + favouriteGenres.hashCode();
        result = 31 * result + age;
        return result;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Reader reader = (Reader) o;

        if (age != reader.age) return false;
        if (!favouriteBooks.equals(reader.favouriteBooks)) return false;
        return favouriteGenres.equals(reader.favouriteGenres);
    }
}

BookSuggestionService.java

class BookSuggestionService {

    private final Set<Book> books;
    private final Set<Reader> readers;

    public BookSuggestionService(Set<Book> books, Set<Reader> readers) {
        this.books = books;
        this.readers = readers;
    }

    Set<String> suggestBooks(Reader reader) {
        int age = reader.getAge();
        Set<Genre> favouriteGenres = reader.getFavouriteGenres();
        Set<Book> favouriteBooks = reader.getFavouriteBooks();
        throw new UnsupportedOperationException("Please, implement me");
    }

    Set<String> suggestBooks(Reader reader, int rating) {
        throw new UnsupportedOperationException("Please, implement me");
    }

    Set<String> suggestBooks(Reader reader, Author author) {
        throw new UnsupportedOperationException("Please, implement me");
    }
}

和测试类我开发..

private Author jemisin = new Author("N.K.", "Jemisin");
    private Author bloch = new Author("Joshua", "Bloch");
    private Author neuvel = new Author("Sylvain", "Neuvel");
    private Author duckworth = new Author("Angela", "Duckworth");
    private Author bennett = new Author("Robert", "Bennett");
    private Book fifthSeason = new Book(jemisin, "The Fifth Season", "0316229296", FANTASY, 5);
    private Book obeliskGate = new Book(jemisin, "The Obelisk Gate", "0356508366", FANTASY, 4);
    private Book sleepingGiants = new Book(neuvel, "Sleeping Giants", "1101886692", FANTASY, 3);
    private Book effectiveJava = new Book(bloch, "Effective Java", " 0321356683", TECH, 5);
    private Book cityOfStairs = new Book(bennett, "City of Stairs", "080413717X", FANTASY, 5);
    private Book grit = new Book(duckworth, "Grit", "1501111108", NON_FICTION, 5);
    private Reader sara = new Reader(18);
    private Reader john = new Reader(18);
    private Reader anastasia = new Reader(44);
    private BookSuggestionService suggestionService;

    @Before
    public void setUp() {
        sara.addToFavourites(FANTASY);
        sara.addToFavourites(TECH);
        john.addToFavourites(obeliskGate);
        john.addToFavourites(fifthSeason);
        john.addToFavourites(sleepingGiants);
        john.addToFavourites(effectiveJava);
        anastasia.addToFavourites(cityOfStairs);
        Set<Book> books = newHashSet(fifthSeason, obeliskGate, sleepingGiants, effectiveJava, cityOfStairs, grit);
        Set<Reader> readers = newHashSet(sara, john, anastasia);
        suggestionService = new BookSuggestionService(books, readers);
    }

    @Test
    public void shouldSuggestBookTitlesWithDefaultRatingOfFourOrHigher() throws Exception {
        // when:
        Set<String> suggestedBooks = suggestionService.suggestBooks(sara);

        // then:
        assertThat(suggestedBooks).isEqualTo(newHashSet(fifthSeason.getTitle(), obeliskGate.getTitle(),
                effectiveJava.getTitle()));
    }
}

1 个答案:

答案 0 :(得分:0)

类BookSuggestionService {

private final Set<Book> books;
private final Set<Reader> readers;
Predicate<Book> predicate = (book) -> book.getRating() > 3;

public BookSuggestionService(Set<Book> books, Set<Reader> readers) {
    this.books = books;
    this.readers = readers;
}

Set<String> suggestBooks(Reader reader) {
    Set<String> suggestedBooks = new TreeSet<>();

    Set<Book> bookSet = rating(books, predicate);
    bookSet = favouriteGenre(bookSet);
    bookSet = favouriteBooks(bookSet);
    suggestedBooks = getName(bookSet);
    return suggestedBooks;
}

Set<String> suggestBooks(Reader reader, int rating) {
    Set<String> suggestedBooks = new TreeSet<>();
    Set<Book> bookSet = rating(books, (book) -> book.getRating() == rating);
    bookSet = favouriteGenre(bookSet);
    bookSet = favouriteBooks(bookSet);
    suggestedBooks = getName(bookSet);
    return suggestedBooks;
}

Set<String> suggestBooks(Reader reader, Author author) {
    Set<String> suggestedBooks = new TreeSet<>();
    Set<Book> bookSet = rating(books, predicate);
    bookSet = favouriteGenre(bookSet);
    bookSet = favouriteBooks(bookSet);
    bookSet = writtenBy(bookSet, author);
    suggestedBooks = getName(bookSet);
    return suggestedBooks;
}


private Set<Book> rating(Set<Book> bookSet, Predicate<Book> predicate) {
    Set<Book> books = new HashSet<>();
    for (Book book : bookSet) {
        if (predicate.test(book))
            books.add(book);
    }
    return books;
}

private Set<Book> favouriteGenre(Set<Book> bookSet) {
    Set<Book> books = new HashSet<>();

    for (Book book : bookSet) {
        for (Reader reader : readers) {
            if (reader.getFavouriteGenres().contains(book.getGenre())) {
                books.add(book);
                break;
            }
        }
    }
    return books;
}

private Set<Book> favouriteBooks(Set<Book> bookSet) {
    Set<Book> books = new HashSet<>();
    int age = 0;
    for (Book book : bookSet) {
        for (Reader reader : readers) {
            if (reader.getFavouriteBooks().contains(book)) {
                if (age == 0) {
                    age = reader.getAge();
                    books.add(book);
                } else if (age == reader.getAge()) {
                    books.add(book);
                }
            }
        }
    }
    return books;
}

private Set<Book> writtenBy(Set<Book> bookSet, Author author) {
    Set<Book> books = new HashSet<>();
    for (Book book : bookSet) {
        if (book.getAuthor().equals(author)) {
            books.add(book);
        }
    }
    return books;
}

private Set<String> getName(Set<Book> bookSet) {
    Set<String> books = bookSet.stream().map(Book::getTitle).collect(Collectors.toSet());
    return books;
}

}