brainfrz

Untitled

Oct 21st, 2015
219
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 19.52 KB | None | 0 0
  1. /**************************************************************************************************
  2.  *  Program Name:     Programming Project 5.7: Bookshelf
  3.  *  Class Name:       pp5_7.Bookshelf
  4.  *  Author:           Terry Weiss
  5.  *  Date Written:     October 15, 2015
  6.  *  Program Description:
  7.  *     This class contains instance data for a bookshelf that is full of `Book`s. It allows the
  8.  *  User to store a book, browse the list of books, view the details of a particular book and
  9.  *  take a book off the shelf.
  10.  **************************************************************************************************/
  11. package pp5_7;
  12.  
  13. //import pp5_7.Book;
  14. import java.util.ArrayList;
  15. import java.util.Collections;
  16. import java.util.List;
  17. import java.util.Scanner;
  18.  
  19.  
  20. /**
  21.  * Contains instance data for a bookshelf that is full of {@link pp5_7.Book}s. It allows the User to
  22.  * store a book, browse the list of books, view the details of a particular book and take a book off
  23.  * the Bookshelf.
  24.  *
  25.  * @author Terry Weiss
  26.  * @see    pp5_7.Book
  27.  * @see    pp5_7.Librarian
  28. */
  29. public class Bookshelf {
  30.     private final String DEFAULT_NAME = "Bookshelf";
  31.  
  32.     /*
  33.      *  Holds all {@link pp5_7.Book}s, genres and authors. Genres and authors are saved here to be
  34.      *  quickly referenced when browsing by category.
  35.      */
  36.     private List<Book> bookList;
  37.     private List<String> genreList = new ArrayList<>();
  38.     private List<String> authorList = new ArrayList<>();
  39.     private final String name;
  40.  
  41.  
  42.     /**
  43.      * Constructs a new Bookshelf instance using the default name.
  44.      */
  45.     public Bookshelf() {
  46.         name = DEFAULT_NAME;
  47.         bookList = new ArrayList<>();
  48.     }
  49.  
  50.     /**
  51.      * Constructs a new Bookshelf instance using the name provided.
  52.      *
  53.      * @param name Name of the bookshelf
  54.      */
  55.     public Bookshelf( String name ) {
  56.         this.name = name;
  57.         bookList = new ArrayList<>();
  58.     }
  59.  
  60.     /**
  61.      * Constructs a new Bookshelf instance, using the default name, populated by a list of
  62.      * {@link pp5_7.Book}s. Bookshelf's size will be originally allocated to 150% the size of the
  63.      * loaded list.
  64.      *
  65.      * @param loadedList Bookshelf to be loaded
  66.      */
  67.     public Bookshelf( List<Book> loadedList ) {
  68.         name = DEFAULT_NAME;
  69.         // Initialize with more space following default +10 rule
  70.         bookList = new ArrayList<>(loadedList.size() + 10);
  71.  
  72.         // Add each book "manually" instead of copying everything, in case handling changes later.
  73.         for ( Book book : loadedList ) {
  74.             addBook(book);
  75.         }
  76.     }
  77.  
  78.     /**
  79.      * Constructs a new Bookshelf instance, using the specified name, populated by a list of
  80.      * {@link pp5_7.Book}s. Bookshelf's size will be originally allocated to 150% the size of the
  81.      * loaded list.
  82.      *
  83.      * @param loadedList Bookshelf to be loaded
  84.      * @param name Name of the bookshelf
  85.      */
  86.     public Bookshelf( List<Book> loadedList, String name ) {
  87.         this.name = name;
  88.         bookList = new ArrayList<>(loadedList.size() + 10);
  89.  
  90.         for (Book book : loadedList) {
  91.             addBook(book);
  92.         }
  93.     }
  94.  
  95.  
  96.     /**
  97.      * Gives current number of {@link pp5_7.Book}s on the shelf.
  98.      *
  99.      * @return Number of Books
  100.      */
  101.     public int getNumberOfBooks() {
  102.         return bookList.size();
  103.     }
  104.  
  105.     /**
  106.      * Provides the current list of {@link pp5_7.Book}s on the shelf as a
  107.      * {@link java.util.List}.
  108.      *
  109.      * @return All Book objects in a List
  110.      */
  111.     public List<Book> getBookList() {
  112.         return bookList;
  113.     }
  114.  
  115.     /**
  116.      * Provides a {@link pp5_7.Book} object from the shelf, retrieved by its location.
  117.      *
  118.      * @param location Location of the desired book
  119.      * @return Book object retrieved
  120.      */
  121.     public Book getBook( int location ) {
  122.         return bookList.get(location);
  123.     }
  124.  
  125.     /**
  126.      * Provides a {@link pp5_7.Book} object from the shelf, retrieved by its title.
  127.      *
  128.      * @param title Title of the desired book
  129.      * @return Book object retrieved
  130.      */
  131.     public Book getBook( String title ) {
  132.         return bookList.get(findBook(title));
  133.     }
  134.  
  135.     /**
  136.      * Gives the name of the bookshelf.
  137.      *
  138.      * @return Bookshelf's name
  139.      */
  140.     public String getName() {
  141.         return name;
  142.     }
  143.  
  144.  
  145.     /**
  146.      * Adds a pre-created {@link pp5_7.Book} to the shelf.
  147.      *
  148.      * @param book Book instance to be added
  149.      * @return Book instance that was added
  150.      */
  151.     public final Book addBook( Book book ) {
  152.         bookList.add(book);
  153.  
  154.         String genre = book.getGenre();
  155.         if (!genreList.contains(genre)) {
  156.             genreList.add(genre);
  157.         }
  158.  
  159.         String author = book.getAuthor();
  160.         if (!authorList.contains(author)) {
  161.             authorList.add(author);
  162.         }
  163.  
  164.         return book;
  165.     }
  166.  
  167.     /**
  168.      * Removes a specific {@link pp5_7.Book} object from the Bookshelf.
  169.      *
  170.      * @param book Book instance to be removed
  171.      * @return <tt>true</tt> if the Book was successfully removed
  172.      */
  173.     public boolean removeBook( Book book ) {
  174.         // If it's the only book of that genre or author, remove the genre/author from its list
  175.         String genre = book.getGenre();
  176.         if (numBooksWithGenre(genre) == 1) {
  177.             genreList.remove(genre);
  178.         }
  179.  
  180.         String author = book.getAuthor();
  181.         if (numBooksWithAuthor(author) == 1) {
  182.             authorList.remove(author);
  183.         }
  184.  
  185.         return bookList.remove(book);
  186.     }
  187.  
  188.     /**
  189.      * Removes {@link pp5_7.Book} from the Bookshelf. Replaced by
  190.      * {@link #removeBook(java.lang.String)}. Only use if the book being removed must be saved,
  191.      * since the positions change with each sort.
  192.      *
  193.      * @param position Position of the Book in the list
  194.      * @return Book instance being removed
  195.      */
  196.     public Book removeBook( int position ) {
  197.         Book book = bookList.get(position);
  198.  
  199.         String genre = book.getGenre();
  200.         if (numBooksWithGenre(genre) == 1) {
  201.             genreList.remove(genre);
  202.         }
  203.  
  204.         String author = book.getAuthor();
  205.         if (numBooksWithGenre(genre) == 1) {
  206.             authorList.remove(author);
  207.         }
  208.  
  209.         return bookList.remove(position);
  210.     }
  211.  
  212.     /**
  213.      * Removes {@link pp5_7.Book} from the Bookshelf.
  214.      *
  215.      * @param title Title of the Book to be removed
  216.      * @return <tt>true</tt> if the Book was successfully removed
  217.      */
  218.     public boolean removeBook( String title ) {
  219.         if (numBooksWithTitle(title) == 1) {
  220.             removeBook(findBook(title));
  221.             return true;
  222.         }
  223.         else {
  224.             return false;
  225.         }
  226.     }
  227.  
  228.     /**
  229.      * Removes all {@link pp5_7.Book}s from the Bookshelf.
  230.      *
  231.      * @return List of Books prior to deletion
  232.      */
  233.     public List<Book> emptyBookshelf() {
  234.         List<Book> list = bookList;
  235.  
  236.         for (int i = 0; i < bookList.size(); i++) {
  237.             removeBook(i);
  238.         }
  239.  
  240.         return list;
  241.     }
  242.  
  243.  
  244.     /**
  245.      * Provides details of a specific {@link pp5_7.Book} from the Bookshelf, or if the Book doesn't
  246.      * exist. Only use in cases where you want only one version of a Book that has a non-unique
  247.      * title, since the positions change with each sort.
  248.      *
  249.      * @param position Position of Book to be viewed
  250.      * @deprecated Replaced by {@link #viewBook(java.lang.String)}
  251.      * @return String holding the details of the book if it exists
  252.      */
  253.     public String viewBook( int position ) {
  254.         String ret;
  255.  
  256.         if (position < 0 || position >= bookList.size()) {
  257.             ret = "That book isn't on the shelf.";
  258.         }
  259.         else {
  260.             ret = bookList.get(position).displayDetails();
  261.         }
  262.  
  263.         return ret;
  264.     }
  265.  
  266.     /**
  267.      * Provides details of a specific {@link pp5_7.Book} from the Bookshelf, or if the Book doesn't
  268.      * exist. In cases where the title isn't unique, all Books by this title are shown and separated
  269.      * by an empty line.
  270.      *
  271.      * @param title Title of the Book
  272.      * @return String holding the details of the Books by that title
  273.      */
  274.     public String viewBook( String title ) {
  275.         String details = "";
  276.  
  277.         for (Book currentBook : bookList) {
  278.             if (currentBook.getTitle().equalsIgnoreCase(title)) {
  279.                 if (details.length() > 0) {  // Separate each entry by a blank line in cases
  280.                     details += "\n\n";       // of duplicate titles
  281.                 }
  282.  
  283.                 details += currentBook.displayDetails();
  284.             }
  285.         }
  286.  
  287.         if (details.length() == 0) {
  288.             details = title + " isn't on the shelf.";
  289.         }
  290.  
  291.         return details;
  292.     }
  293.  
  294.  
  295.     /**
  296.      * Sorts all {@link pp5_7.Book}s in ascending alphabetical order by title.
  297.      *
  298.      * @see pp5_7.Book#sortByTitle
  299.      */
  300.     public void sortBooksByTitle() {
  301.         Collections.sort(bookList, Book.sortByTitle);
  302.     }
  303.  
  304.     /**
  305.      * Sorts all {@link pp5_7.Book}s in ascending alphabetical by Author first and then by Title.
  306.      *
  307.      * @see pp5_7.Book#sortByAuthor
  308.      */
  309.     public void sortBooksByAuthor() {
  310.         // Sorts must be done in reverse order to get benefit of sorting by Title while not
  311.         // overriding the sort by author.
  312.         sortBooksByTitle();
  313.         Collections.sort(bookList, Book.sortByAuthor);
  314.     }
  315.  
  316.     /**
  317.      * Sorts all {@link pp5_7.Book}s in ascending alphabetical by Genre first and then by Title.
  318.      *
  319.      * @see pp5_7.Book#sortByGenre
  320.      */
  321.     public void sortBooksByGenre() {
  322.         sortBooksByTitle();
  323.         Collections.sort(bookList, Book.sortByGenre);
  324.     }
  325.  
  326.     /**
  327.      * Sorts all {@link pp5_7.Book}s in ascending numerical order by size first and then by Title
  328.      * in cases where two books are the same size.
  329.      */
  330.     public void sortBooksBySize() {
  331.         sortBooksByTitle();
  332.         Collections.sort(bookList);
  333.     }
  334.  
  335.  
  336.     /**
  337.      * Returns the index of the first occurrence of the {@link pp5_7.Book} in this list, or -1 if
  338.      * this list does not contain the Book.
  339.      *
  340.      * @param book Book object to search for
  341.      * @return Index of the first Book, or <tt>-1</tt> if it's not there
  342.      */
  343.     public int findBook( Book book ) {
  344.         return bookList.indexOf(book);
  345.     }
  346.  
  347.     /**
  348.      * Returns the index of the first occurrence of the {@link pp5_7.Book} of the same title in this
  349.      * list, or -1 if this list does not contain the Book.
  350.      *
  351.      * @param title Title of the book to search for
  352.      * @return Index of the first Book, or <tt>-1</tt> if it's not there
  353.      */
  354.     public int findBook( String title ) {
  355.         for (int currentBook = 0; currentBook < bookList.size(); currentBook++) {
  356.             String currentTitle = bookList.get(currentBook).getTitle();
  357.             if (currentTitle.equalsIgnoreCase(title)) {
  358.                 return currentBook;
  359.             }
  360.         }
  361.  
  362.         return -1;
  363.     }
  364.  
  365.  
  366.     /**
  367.      * Provides the number of {@link pp5_7.Book}s of a certain genre.
  368.      *
  369.      * @param genre Name of the genre
  370.      * @return Number of Books of the provided genre
  371.      */
  372.     public int numBooksWithGenre( String genre ) {
  373.         int books = 0;
  374.  
  375.         for (Book book : bookList ) {
  376.             if (book.getGenre().equalsIgnoreCase(genre)) {
  377.                 books++;
  378.             }
  379.         }
  380.  
  381.         return books;
  382.     }
  383.  
  384.     /**
  385.      * Provides the number of {@link pp5_7.Book}s of a certain author.
  386.      *
  387.      * @param author Name of the author
  388.      * @return Number of Books by the provided author
  389.      */
  390.     public int numBooksWithAuthor( String author ) {
  391.         int books = 0;
  392.  
  393.         for (Book book : bookList ) {
  394.             if (book.getAuthor().equalsIgnoreCase(author)) {
  395.                 books++;
  396.             }
  397.         }
  398.  
  399.         return books;
  400.     }
  401.  
  402.     /**
  403.      * Provides the number of {@link pp5_7.Book}s of a certain title.
  404.      *
  405.      * @param title Title to be searched for
  406.      * @return Number of Books of the same title
  407.      */
  408.     public int numBooksWithTitle( String title ) {
  409.         int books = 0;
  410.  
  411.         for (Book book : bookList ) {
  412.             if (book.getTitle().equalsIgnoreCase(title)) {
  413.                 books++;
  414.             }
  415.         }
  416.  
  417.         return books;
  418.     }
  419.  
  420.  
  421.     /**
  422.      * Provides a String of all {@link pp5_7.Book}s on the Bookshelf using their String
  423.      * representation.
  424.      *
  425.      * @return List of all Books on the Bookshelf
  426.      */
  427.     public String browse() {
  428.         String list = "";
  429.  
  430.         for (Book currentBook : bookList) {
  431.             list += currentBook + "\n";
  432.         }
  433.  
  434.         return list;
  435.     }
  436.  
  437.     /**
  438.      * Provides a String of all {@link pp5_7.Book}s on the Bookshelf using their String
  439.      * representation. Books are resorted by title.
  440.      *
  441.      * @return List of all Books on the Bookshelf, sorted by title
  442.      * @see #sortBooksByTitle
  443.      */
  444.     public String browseByTitle() {
  445.         sortBooksByTitle();
  446.         return browse();
  447.     }
  448.  
  449.     /**
  450.      * Provides a String of all {@link pp5_7.Book}s on the Bookshelf using their String
  451.      * representation. Books are resorted by author's last name.
  452.      *
  453.      * @return List of all Books on the Bookshelf, sorted by author
  454.      * @see #sortBooksByAuthor
  455.      */
  456.     public String browseByAuthor() {
  457.         sortBooksByAuthor();
  458.         String list = "";
  459.  
  460.         for (Book currentBook : bookList ) {
  461.             list += String.format("%-20s    %s\n", currentBook, currentBook.getAuthor());
  462.         }
  463.  
  464.         return list;
  465.     }
  466.  
  467.     /**
  468.      * Provides a String of all {@link pp5_7.Book}s on the Bookshelf using their String
  469.      * representation. Books are resorted by genre.
  470.      *
  471.      * @return List of all Books on the Bookshelf, sorted by genre
  472.      * @see #sortBooksByGenre
  473.      */
  474.     public String browseByGenre() {
  475.         sortBooksByGenre();
  476.         String list = "";
  477.  
  478.         for (Book currentBook : bookList ) {
  479.             list += String.format("%-20s    %s\n", currentBook, currentBook.getGenre());
  480.         }
  481.  
  482.         return list;
  483.     }
  484.  
  485.     /**
  486.      * Provides a String of all {@link pp5_7.Book}s on the Bookshelf using their String
  487.      * representation. Books are resorted by size.
  488.      *
  489.      * @return List of all Books on the Bookshelf, sorted by size
  490.      * @see #sortBooksBySize
  491.      */
  492.     public String browseBySize() {
  493.         sortBooksBySize();
  494.         String list = "";
  495.  
  496.         for (Book currentBook : bookList ) {
  497.             list += String.format("%-20s    %s\n", currentBook, currentBook.getPages());
  498.         }
  499.  
  500.         return list;
  501.     }
  502.  
  503.     /**
  504.      * Provides a String of all {@link pp5_7.Book}s on the Bookshelf in a specific genre, or if
  505.      * no books in that genre exist. Books are sorted by title.
  506.      *
  507.      * @param genre Genre to be listed
  508.      * @return List of Books in the given genre
  509.      */
  510.     public String browseBooksOfGenre( String genre ) {
  511.         String list = "";
  512.  
  513.         // Make the genre Capitalized to match format of genres and be case-insensitive
  514.         genre = genre.substring(0, 1).toUpperCase() + genre.substring(1).toLowerCase();
  515.  
  516.         if (genreList.indexOf(genre) == -1) {
  517.             list = "There are no books of that genre.\n";
  518.         }
  519.         else {
  520.             sortBooksByGenre();
  521.             int i = 0;
  522.  
  523.             // Find first book with the genre
  524.             while (!bookList.get(i).getGenre().equalsIgnoreCase(genre)) {
  525.                 i++;
  526.             }
  527.  
  528.             // Display all books until the genre changes or until it's the last book of the shelf
  529.             while (i < bookList.size() && bookList.get(i).getGenre().equalsIgnoreCase(genre)) {
  530.                 list += bookList.get(i) + "\n";
  531.                 i++;
  532.             }
  533.         }
  534.  
  535.         return list;
  536.     }
  537.  
  538.     /**
  539.      * Provides a String of all {@link pp5_7.Book}s on the Bookshelf by a specific author, or if
  540.      * no books by that author exist. Books are sorted by title.
  541.      *
  542.      * @param author Author to be listed
  543.      * @return List of Books by the given author
  544.      */
  545.     public String browseBooksOfAuthor( String author ) {
  546.         String list = "";
  547.  
  548.         // Make the genre Capitalized to match format of genres and be case-insensitive
  549.         String capitalizedAuthor = "";
  550.         for (String authorName : author.split(" ")) {
  551.             capitalizedAuthor += authorName.substring(0, 1).toUpperCase()
  552.                                     + authorName.substring(1).toLowerCase() + " ";
  553.         }
  554.         capitalizedAuthor = capitalizedAuthor.trim();
  555.  
  556.         if (authorList.indexOf(capitalizedAuthor) == -1) {
  557.             list = "There are no books by that author.\n";
  558.         }
  559.         else {
  560.             sortBooksByAuthor();
  561.             int i = 0;
  562.  
  563.             // Find first book with the genre
  564.             while (!bookList.get(i).getAuthor().equalsIgnoreCase(capitalizedAuthor)) {
  565.                 i++;
  566.             }
  567.  
  568.             // Display all books until the genre changes or until it's the last book of the shelf
  569.             while (i < bookList.size() && bookList.get(i).getAuthor()
  570.                                                             .equalsIgnoreCase(capitalizedAuthor)) {
  571.                 list += bookList.get(i) + "\n";
  572.                 i++;
  573.             }
  574.         }
  575.  
  576.         return list;
  577.     }
  578.  
  579.     /**
  580.      * Provides a String of all {@link pp5_7.Book}s on the Bookshelf in a specific category, or if
  581.      * no books in that category exist. Books are sorted by title. Currently, the only supported
  582.      * categories are <tt>"author"</tt> and <tt>"genre"</tt>.
  583.      *
  584.      * @param category Category to be used
  585.      * @return List of Books in the given category
  586.      */
  587.     public String browseByCategory( String category ) {
  588.         String list = "";
  589.  
  590.         if (category.equalsIgnoreCase("author") || category.equalsIgnoreCase("authors")) {
  591.             for (String author : authorList) {
  592.                 list += author + ":\n"
  593.                       + browseBooksOfAuthor(author) + "\n";
  594.             }
  595.         }
  596.         else if (category.equalsIgnoreCase("genre") || category.equalsIgnoreCase("genres")) {
  597.             for (String genre : genreList) {
  598.                 list += genre + ":\n"
  599.                       + browseBooksOfGenre(genre) + "\n";
  600.             }
  601.         }
  602.         else {
  603.             list = "No such category.\n";
  604.         }
  605.  
  606.         return list;
  607.     }
  608.  
  609.  
  610.  
  611.     /**
  612.      * String representation of the Bookshelf
  613.      *
  614.      * @return Bookshelf's name
  615.      */
  616.     @Override
  617.     public String toString() {
  618.         return getName();
  619.     }
  620.  
  621.  
  622.  
  623.  
  624.     /**
  625.      * Used only for debugging purposes
  626.      *
  627.      * @param args Command line input isn't supported
  628.      */
  629.     public static void main( String[] args ) {
  630.         Scanner user_input = new Scanner(System.in);
  631.  
  632.         Bookshelf myShelf = new Bookshelf();
  633.         myShelf.addBook(new Book("book1", 321, "martin", "fiction"));
  634.         myShelf.addBook(new Book("book2", 123, "Martin", "non-fiction"));
  635.         myShelf.addBook(new Book("book3", 852, "Peter", "sci-fi"));
  636.         myShelf.addBook(new Book("book4", 753, "Martin", "fiction"));
  637.         myShelf.addBook(new Book("book5", 159, "Ralph", "non-fiction"));
  638.         myShelf.addBook(new Book("book6", 349, "MartIn", "fiction"));
  639.  
  640.         myShelf.removeBook("book2");
  641.  
  642.         System.out.print(myShelf.browseByCategory("author"));
  643.  
  644.         System.out.println(myShelf.viewBook("book1"));
  645.     }
  646. }
Advertisement
Add Comment
Please, Sign In to add comment