问题
I have developed a program that creates an array of Book Objects and sorts them based on user input. The sorting options are author-title-pages-price, and all work but the price sort. Please help me find why I cannot sort doubles using Comparator... My SchoolTextBook Class:
import java.util.Comparator;
public class SchoolTextBook {
private String author;
private String title;
private int pageCount;
private String ISBN;
private double price;
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getPageCount() {
return pageCount;
}
public void setPageCount(int pageCount) {
this.pageCount = pageCount;
}
public String getISBN() {
return ISBN;
}
public void setISBN(String iSBN) {
ISBN = iSBN;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public static Comparator<SchoolTextBook> BookAuthorComparator
= new Comparator<SchoolTextBook>() {
public int compare(SchoolTextBook book1, SchoolTextBook book2) {
String bookName1 = book1.getAuthor().toUpperCase();
String bookName2 = book2.getAuthor().toUpperCase();
//ascending order
return bookName1.compareTo(bookName2);
}
};
public static Comparator<SchoolTextBook> BookTitleComparator
= new Comparator<SchoolTextBook>() {
public int compare(SchoolTextBook book1, SchoolTextBook book2) {
String bookName1 = book1.getTitle().toUpperCase();
String bookName2 = book2.getTitle().toUpperCase();
//ascending order
return bookName1.compareTo(bookName2);
}
};
public static Comparator<SchoolTextBook> BookPagesComparator
= new Comparator<SchoolTextBook>() {
public int compare(SchoolTextBook book1, SchoolTextBook book2) {
int bookName1 = book1.getPageCount();
int bookName2 = book2.getPageCount();
//ascending order
return bookName1 - bookName2;
}
};
public static Comparator<SchoolTextBook> BookPriceComparator
= new Comparator<SchoolTextBook>() {
public int compare(SchoolTextBook book1, SchoolTextBook book2) {
double bookName1 = book1.getPrice();
double bookName2 = book2.getPrice();
//ascending order
return (int) (bookName1 - bookName2);
}
};
}
And the sort program:
import java.util.Arrays;
import java.util.*;
import javax.swing.*;
public class SchoolTextBookSort {
public static void main(String[] args) {
// TODO Auto-generated method stub
String[] choices = {"Author", "Title", "Page Count", "Price"};
SchoolTextBook[] theBooks = new SchoolTextBook[5];
theBooks[0] = new SchoolTextBook();
theBooks[1] = new SchoolTextBook();
theBooks[2] = new SchoolTextBook();
theBooks[3] = new SchoolTextBook();
theBooks[4] = new SchoolTextBook();
theBooks[0].setAuthor("Ernest Hemingway");
theBooks[1].setAuthor("Mark Twain");
theBooks[2].setAuthor("William Shakespeare");
theBooks[3].setAuthor("Stephen King");
theBooks[4].setAuthor("William Faulkner");
theBooks[0].setTitle("A Farewell to Arms");
theBooks[1].setTitle("The Adventures of Huckleberry Finn");
theBooks[2].setTitle("Hamlet");
theBooks[3].setTitle("Salem's Lot");
theBooks[4].setTitle("The Sound and the Fury");
theBooks[0].setPageCount(332);
theBooks[1].setPageCount(320);
theBooks[2].setPageCount(196);
theBooks[3].setPageCount(439);
theBooks[4].setPageCount(326);
theBooks[0].setISBN("0099910101");
theBooks[1].setISBN("0142437174");
theBooks[2].setISBN("0521618746");
theBooks[3].setISBN("0450031063");
theBooks[4].setISBN("0679732241");
theBooks[0].setPrice(5.99);
theBooks[1].setPrice(7.60);
theBooks[2].setPrice(9.41);
theBooks[3].setPrice(16.56);
theBooks[4].setPrice(9.60);
int response = JOptionPane.showOptionDialog(
null // Center in window.
, "Please select a method to sort the books." // Message
, "Sort Text Books" // Title in titlebar
, JOptionPane.YES_NO_OPTION // Option type
, JOptionPane.PLAIN_MESSAGE // messageType
, null // Icon (none)
, choices // Button text as above.
, null // Default button's label
);
//... Use a switch statement to check which button was clicked.
switch (response) {
case 0:
Arrays.sort(theBooks, SchoolTextBook.BookAuthorComparator);
break;
case 1:
Arrays.sort(theBooks, SchoolTextBook.BookTitleComparator);
break;
case 2:
Arrays.sort(theBooks, SchoolTextBook.BookPagesComparator);
break;
case 3:
Arrays.sort(theBooks, SchoolTextBook.BookPriceComparator);
case -1:
//... Both the quit button (3) and the close box(-1) handled here.
System.exit(0); // It would be better to exit loop, but...
default:
//... If we get here, something is wrong. Defensive programming.
JOptionPane.showMessageDialog(null, "Unexpected response " + response);
}
show(theBooks);
}
public static String show(SchoolTextBook[] theBooks) {
StringBuilder sb = new StringBuilder(64);
sb.append("<html><table><tr><td>Author</td><td>Title</td><td>ISBN</td><td>Pages</td><td>Price</td></tr>");
sb.append("<tr>");
sb.append("<td>").append(theBooks[0].getAuthor()).append("</td>");
sb.append("<td>").append(theBooks[0].getTitle()).append("</td>");
sb.append("<td>").append(theBooks[0].getISBN()).append("</td>");
sb.append("<td>").append(theBooks[0].getPageCount()).append("</td>");
sb.append("<td>").append("$" + theBooks[0].getPrice()).append("</td></tr>");
sb.append("<tr>");
sb.append("<td>").append(theBooks[1].getAuthor()).append("</td>");
sb.append("<td>").append(theBooks[1].getTitle()).append("</td>");
sb.append("<td>").append(theBooks[1].getISBN()).append("</td>");
sb.append("<td>").append(theBooks[1].getPageCount()).append("</td>");
sb.append("<td>").append("$" + theBooks[1].getPrice()).append("</td></tr>");
sb.append("<tr>");
sb.append("<td>").append(theBooks[2].getAuthor()).append("</td>");
sb.append("<td>").append(theBooks[2].getTitle()).append("</td>");
sb.append("<td>").append(theBooks[2].getISBN()).append("</td>");
sb.append("<td>").append(theBooks[2].getPageCount()).append("</td>");
sb.append("<td>").append("$" + theBooks[2].getPrice()).append("</td></tr>");
sb.append("<tr>");
sb.append("<td>").append(theBooks[3].getAuthor()).append("</td>");
sb.append("<td>").append(theBooks[3].getTitle()).append("</td>");
sb.append("<td>").append(theBooks[3].getISBN()).append("</td>");
sb.append("<td>").append(theBooks[3].getPageCount()).append("</td>");
sb.append("<td>").append("$" + theBooks[3].getPrice()).append("</td></tr>");
sb.append("<tr>");
sb.append("<td>").append(theBooks[4].getAuthor()).append("</td>");
sb.append("<td>").append(theBooks[4].getTitle()).append("</td>");
sb.append("<td>").append(theBooks[4].getISBN()).append("</td>");
sb.append("<td>").append(theBooks[4].getPageCount()).append("</td>");
sb.append("<td>").append("$" + theBooks[4].getPrice()).append("</td>");
sb.append("</tr></table></html>");
JOptionPane.showMessageDialog(null, sb);
return sb.toString();
}
}
回答1:
With your existing solution you are casting the difference to int
which will not work in all case, for example 2.5
and 2.6
will resolve to (int)(2.6- 2.5)
= 0
that means both of them are same to avoid it
Use Double.compare(double, double) instead
public static Comparator<SchoolTextBook> BookPriceComparator
= new Comparator<SchoolTextBook>() {
public int compare(SchoolTextBook book1, SchoolTextBook book2) {
double price1 = book1.getPrice();
double price2 = book2.getPrice();
//ascending order
return Double.compare(price1, price2);
}
};
回答2:
double bookName1 = book1.getPrice();
double bookName2 = book2.getPrice();
//ascending order
return (int) (bookName1 - bookName2);
Suppose the prices are 0.99 and 0.5. The result is thus (int) (0.49)
, which is 0. And two books with different prices are thus considered equal by your comparator.
Don't cast doubles to int, since it obviously loses precision. Use the appropriate comparison method instead:
return Double.compare(book1.getPrice(), book2.getPrice());
回答3:
public static int compare(double d1,
double d2)
Compares the two specified double values. The sign of the integer value returned is the same as that of the integer that would be returned by the call:
new Double(d1).compareTo(new Double(d2))
来源:https://stackoverflow.com/questions/24959250/comparator-double-does-not-work