/**************************************************************************************************
* 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<Book> {
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<Book> 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<Book> 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<Book> 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
***********************************************************************************************/
Comments