Java Complex Sorting
I am stuck in that I have an Object Book that got three variables
String title
int Year
String authorName
I must sort the books by one, two or all three of the variables in ascending or descending order, I implemented the title ordering but I am stuck as to what to do when people choose more than one variable to order.
Here is some of my code:
Book Class:
import java.util.ArrayList;
public class Book{
String title;
String authorName;
int editionYear;
public Book(String title, String authorName, int editionYear){
this.title = title;
this.authorName = authorName;
this.editionYear = editionYear;
}
public String getBookInfo(){
ArrayList bookInfo = new ArrayList();
bookInfo.add(this.title);
bookInfo.add(this.authorName);
bookInfo.add(this.editionYear);
return bookInfo.toString();
}
}
BookSorter Class:
import java.util.Arrays;
import java.util.Comparator;
public class BookSorter{
private String sortkey;
priv开发者_如何学编程ate String order;
Book[] Books;
public BookSorter(Book Book1, Book Book2, Book Book3, Book Book4){
this.Books = new Book[] {Book1, Book2, Book3, Book4};
}
public Book[] sortByTitle(boolean sortorder){
Comparator<Book> byTitle = new TitleComparator(sortorder);
Arrays.sort(Books, byTitle);
for(int i=0;i<4;i++) System.out.println(Books[i].title);
return Books;
}
}
TitleComparator:
import java.util.Comparator;
class TitleComparator implements Comparator<Book> {
boolean ascending;
public TitleComparator(boolean ascending){
this.ascending = ascending;
}
public int compare(Book Book1, Book Book2){
if(ascending == true){
if(Book1.title.compareToIgnoreCase(Book2.title) > 0) return 1;
else if(Book1.title.compareToIgnoreCase(Book2.title) < 0) return -1;
else return 0;
}else{
if(Book2.title.compareToIgnoreCase(Book1.title) < 0) return -1;
else if(Book2.title.compareToIgnoreCase(Book1.title) > 0) return 1;
else return 0;
}
}
}
I though I could work a little more on the comparator but I am really stuck on how to model such a thing, Thanks in advance
Write 3 comparator classes that each compare a specific attribute and then an overall comparator class that takes an ordered list of comparators.
Or use some a convenience class from a library like org.apache.commons.collections.comparators.ComparatorChain.
Edit:
OP asks:
how could I write that overall comparator:
Something like:
// private List<Comparator<?>> comparators; // initialized in constructor
// compare method(book1, book2):
// note that while result == 0, books have had equal attributes so far
// once result is != 0, the books are now ordered - no need to compare further
// if we run out of comparators and result still == 0, books are equal.
// initialize iterator to list of comparators
// int result = 0;
// while result == 0 && still more comparators
// get current comparator from iterator
// result = comparator.compare(book1, book2); // compare current attribute
// end-while
// return result
This sounds like a homework problem. So I am going to provide you with some hints.
1. First see if Title1==Title2.
1.1 if YES then see if year1==year2
1.1.1 if YES then see if authorName1==authorName2
1.1.1.1 If YES then they are equal (return 0)
1.1.1.2 else if NO compare author1 and author2 (return 1 or -1)
1.2 else if NO then compare year1 and year2 (return 1 or -1)
2. else if NO then compare title1 and title2 (return 1 or -1)
The ascending/descending can be implemented much easier, because it simple "inverts" the compare result. And you can "reuse" the results from the compareToIgnoreCase
methods:
public int compare(Book book1, Book book2) {
int result = book1.title.compareToIgnoreCase(book2.title);
return ascending ? result : result * -1;
}
The other comparators are pretty similiar (limiting the samples to the compare method):
public int compare(Book book1, Book book2) {
int result = book1.author.compareToIgnoreCase(book2.author);
return ascending ? result : result * -1;
}
public int compare(Book book1, Book book2) {
Integer year1 = book1.year;
Integer year2 = book2.year;
int result = year1.compareTo(year2);
return ascending ? result : result * -1;
}
The Group Comparator allows you to sort on multiple properties. You can also use the Bean Comparator so you don't have to keep writing custom Comparators.
精彩评论