/************************************************************************************************** * Program Name: Programming Project 5.7: Bookshelf * Class Name: pp5_7.Book * Author: Terry Weiss * Date Written: October 15, 2015 * Program Description: * This class contains instance data for a book that will be used in `Bookshelf`. It contains * instance data for the title, author, genre, and number of pages. **************************************************************************************************/ package pp5_7; import java.util.Comparator; import java.util.ArrayList; import java.util.Collections; /** * * @author Terry */ public class Book implements Comparable { private static final String DEFAULT_AUTHOR = "Unknown"; private static final String DEFAULT_GENRE = "General"; private static int untitledBooks = 0; // Total count of all untitled books to uniquely name them private String title; private String author; private String genre; private int pages; Book( String title, int pages, String author, String genre ) { setTitle(title); setPages(pages); setAuthor(author); setGenre(genre); } Book( String title, int pages, String author ) { setTitle(title); setPages(pages); setAuthor(author); setGenre(DEFAULT_GENRE); } Book( String title, int pages ) { setTitle(title); setPages(pages); setAuthor(DEFAULT_AUTHOR); setGenre(DEFAULT_GENRE); } private String setTitle( String title ) { if (title.length() == 0) { untitledBooks++; title = "Untitled #" + untitledBooks; } else { title = titleCase(title); } return (this.title = title); } private int setPages( int pages ) { if (pages < 1) { pages = 1; } return (this.pages = pages); } private String setAuthor( String author ) { String fullName = ""; String[] names = author.split(" "); for (int currentName = 0; currentName < names.length - 1; currentName++) { fullName += capitalize(names[currentName]) + " "; } fullName += capitalize(names[names.length - 1]); return (this.author = fullName); } private String setGenre( String genre ) { if (genre.length() == 0) { genre = DEFAULT_GENRE; } else { genre = capitalize(genre); } return (this.genre = genre); } public String getTitle() { return title; } public int getPages() { return pages; } public String getAuthor() { return author; } public String getGenre() { return genre; } public String displayDetails() { String details = "Title: " + title + "\n" + "Author: " + author + "\n" + "Genre: " + genre + "\n" + "Pages: " + pages + "\n"; return details; } private String titleCase( String str ) { String[] words = str.split(" "); String ret; int currentWord; // Always capitalize first and last words, with other words capitalized as needed ret = capitalize(words[0]) + " "; for (currentWord = 1; currentWord < (words.length - 1); currentWord++) { String word = words[currentWord]; if (isTitleWord(word)) { ret += capitalize(word) + " "; } else { ret += word.toLowerCase() + " "; } } if (words.length > 1) { ret += capitalize(words[currentWord]); } return ret; } private String capitalize( String word ) { return word.substring(0, 1).toUpperCase() + word.substring(1).toLowerCase(); } private boolean isTitleWord( String word ) { boolean isCapitalized; word = word.toLowerCase(); // All articles coordinate conjuctions and prepositions are lower case, // per Chicago Manual of Style switch (word) { // Articles: case "a": case "an": case "the": // Coordinate conjunctions: case "and": case "but": case "for": case "nor": case "or": case "so": case "yet": // Most common single-word English prepositions: case "at": case "about": case "above": case "across": case "ago": case "before": case "beside": case "by": case "in": case "into": case "on": case "onto": case "over": case "past": case "since": case "til": case "through": case "to": case "towards": case "until": isCapitalized = false; break; default: isCapitalized = true; } return isCapitalized; } @Override public String toString() { return getTitle(); } /** * Allows Book objects to be sorted by their size with `this.pages` * * @param book2 The second Book object being compared against * @return The number of pages more than the book being compared against */ @Override public int compareTo( Book book2 ) { return this.getPages() - book2.getPages(); } /** * Compares books by their titles in ascending order. */ public static Comparator sortByTitle = (Book book1, Book book2) -> { String bookTitle1 = book1.getTitle(); String bookTitle2 = book2.getTitle(); return bookTitle1.compareTo(bookTitle2); }; /** * Compares books by their authors in ascending order. */ public static Comparator sortByAuthor = (Book book1, Book book2) -> { String bookAuthor1 = book1.getAuthor(); String bookAuthor2 = book2.getAuthor(); return bookAuthor1.compareTo(bookAuthor2); }; /* * Main method is used for debugging and testing purposes on `Book` class */ public static void main( String args[] ) { Scanner user_input = new Scanner(System.in); ArrayList bookList = new ArrayList(6); Book book1, book2, book3, book4, book5, book6; String title, author, genre; int pages; bookList.add(book1 = new Book("peteR pAn", 42, "marTIn", "fIcTIoN")); bookList.add(book2 = new Book("", 234)); bookList.add(book3 = new Book("the wiTCH IS deAD", 50, "bILLy tHOmaS")); bookList.add(book4 = new Book("", 23)); bookList.add(book5 = new Book("gross ON OuT", 80)); bookList.add(book6 = new Book("", 89)); System.out.println("Before sorting:"); for (Book currentBook : bookList) { System.out.println(currentBook); } Collections.sort(bookList, Book.sortByTitle); System.out.println("\nAfter sorting by title:"); for (Book currentBook : bookList) { System.out.printf("%-19s %s\n", currentBook, currentBook.getTitle()); } Collections.sort(bookList, Book.sortByAuthor); System.out.println("\nAfter sorting by author:"); for (Book currentBook : bookList) { System.out.printf("%-19s %s\n", currentBook, currentBook.getAuthor()); } Collections.sort(bookList); System.out.println("\nAfter sorting by size:"); for (Book currentBook : bookList) { System.out.printf("%-19s %d\n", currentBook, currentBook.getPages()); } } } /**OUTPUT OF MAIN************************************************************************************* Before sorting: Peter Pan Untitled #1 The Witch Is Dead Untitled #2 Gross on Out Untitled #3 After sorting by title: Gross on Out Gross on Out Peter Pan Peter Pan The Witch Is Dead The Witch Is Dead Untitled #1 Untitled #1 Untitled #2 Untitled #2 Untitled #3 Untitled #3 After sorting by author: The Witch Is Dead Billy Thomas Peter Pan Martin Gross on Out Unknown Untitled #1 Unknown Untitled #2 Unknown Untitled #3 Unknown After sorting by size: Untitled #2 23 Peter Pan 42 The Witch Is Dead 50 Gross on Out 80 Untitled #3 89 Untitled #1 234 ***********************************************************************************************/