【问题标题】:Comparator double does not work比较器双不工作
【发布时间】:2014-07-25 23:31:43
【问题描述】:

我开发了一个程序,它创建一个书籍对象数组并根据用户输入对它们进行排序。排序选项是 author-title-pages-price,除价格排序外,所有选项都有效。 请帮我找出为什么我不能使用比较器对双打进行排序...... 我的学校课本课:

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);

    }

};
}

还有排序程序:

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();
}

}

【问题讨论】:

  • 你真的必须发布所有这些代码吗?
  • @alfasin 这是一个完全可重现的例子。这就是重点,不是吗?但是,当然,其他排序方法是不必要的。
  • 首先尝试隔离您的问题——通常这是通过设置一个最小的测试用例来完成的。
  • @SotiriosDelimanolis 你不觉得他能想出一个更小的工作例子吗?
  • 对不起,我刚刚复制/粘贴了我的内容,下次我将删除与我的问题无关的不必要代码。

标签: java sorting comparator


【解决方案1】:

使用您现有的解决方案,您将差异转换为int,这在所有情况下都不起作用,例如2.52.6 将解析为(int)(2.6- 2.5) = 0,这意味着它们都是相同的避免它

改用Double.compare(double, double)

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);

假设价格是 0.99 和 0.5。因此结果为(int) (0.49),即0。因此,您的比较器认为两本书价格不同。

不要将双精度数转换为 int,因为它显然会丢失精度。请改用适当的比较方法:

return Double.compare(book1.getPrice(), book2.getPrice());

【讨论】:

  • 说实话,我当时只是想让代码工作,即使它会返回不正确的结果。我不在乎。
【解决方案3】:
public static int compare(double d1,
          double d2)

比较两个指定的双精度值。返回的整数值的符号与调用将​​返回的整数的符号相同:

new Double(d1).compareTo(new Double(d2))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-13
    • 1970-01-01
    • 1970-01-01
    • 2015-10-11
    • 2020-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多