1

我的程序实现了一个Product类,其对象包含以下实例变量:nameprioritypriceamount

LinkedList对. Product_LinkedList

我想首先按优先级(从最低到最高)对列表进行排序。如果优先级相同,则查看价格(从最低到最高),然后查看名称(按字母顺序)。

我已经阅读了很多关于Collections.sort,ComparableComparator. 我相信我需要使用Comparable接口并实现一个compareTo方法。我的想法是,因为priority,pricename都有一个“自然”的顺序,所以使用Comparable.

public class Product extends ProductBase implements PrintInterface, Comparable<Product>{
    private String name;
    private int priority; 
    private int cents;
    private int quantity;

    // setters and getters

    /**
    * Compare current Product object with compareToThis
    * return 0 if priority, price and name are the same for both  
    * return -1 if current Product is less than compareToThis
    * return 1 if current Product is greater than compareToThis
    */ 

    @override
    public int compareTo(Product compareToThis)
}

然后,当我想对我的 LinkedList 进行排序时,我只需调用Collections.sort(LinkedList). 在我开始编写代码之前,你能告诉我我是否遗漏或忘记了什么吗?

** * ** * ** * ****更新* ** * ** * ** * ** * ** * ** * ** * ** * ** * ** *

我刚刚使用 compare 方法创建了一个名为 ProductComparator 的单独类。

这是 LinkedList 类的一部分。

import java.util.Collections;

public class LinkedList {

private ListNode head; 

public LinkedList() { 
    head = null;
}
     // this method will sort the LinkedList using a ProductComparator
public void sortList() {
    ListNode position = head;
    if (position != null) {
        Collections.sort(this, new ProductComparator());
    }
}
// ListNode inner class
private class ListNode {

    private Product item;
    private ListNode link;

    // constructor
    public ListNode(Product newItem, ListNode newLink) {
        item= newItem;
        link = newLink;
    }
}

}

编译时从 IDE 收到以下错误。

Collections 类型中的方法 sort(List, Comparator) 不适用于参数 (LinkedList, ProductComparator)。

有谁知道我为什么会收到此错误并且可以指出我正确的方向来解决它?

4

3 回答 3

3

如果存在“自然”排序,请使用 Comparable。判断顺序是否“自然”的经验法则是,对象的顺序是否始终如此。

话虽如此,使用 Comparable 还是 Camparator 的决定并不是您需要考虑太多的决定。大多数 IDE 都有重构工具,这使得 Comparable 和 Comparator 之间的转换非常容易。所以如果你现在选择走错路,改变它不需要太多的努力。

于 2012-11-24T17:01:33.553 回答
2

您在此处定义的产品顺序非常具体,并且

  • 可能会在您的程序的未来版本中发生变化
  • 可能会通过上下文参数化来丰富
  • 不会涵盖新功能

所以很难说它是“自然的”。

我建议定义一个常量,例如

public static Comparator<Product> STANDARD_COMPARATOR = new Comparator<Product>() {
    public int compare(Product p1, Product p1) {
        return ...
    }
};

然后你就可以轻松地在任何地方排序

Collections.sort(myProductList, Product.STANDARD_COMPARATOR);

随着您添加其他比较器,您的代码将以更好的方式发展。

就像您通常应该更喜欢组合而不是继承一样,您应该尽量避免以不可变的方式定义对象的行为。

于 2012-11-24T16:58:55.387 回答
0

如果您的订单仅基于数字,那Comparable很好。

但是,由于您的顺序(有时)涉及文本的词汇顺序,所以一个Comparator类更好,因为使用 ofComparable意味着使用 String.compareTowhich 会阻止您进行国际化。

实现的单独类Comparator可以使用本地化Collator来比较字符串。例如:

public class ProductComparator
implements Comparator<Product> {
    private final Collator collator;

    public ProductComparator() {
        this(Locale.getDefault());
    }

    public ProductComparator(Locale locale) {
        this.collator = Collator.getInstance(locale);
    }

    public int compare(Product product1,
                       Product product2) {

        int c = product1.getPriority() - product2.getPriority();
        if (c == 0) {
            c = product1.getPrice() - product2.getPrice();
        }
        if (c == 0) {
            c = collator.compare(product1.getName(), product2.getName());
        }
        return c;
    }
}

无论您使用 Comparable 还是 Comparator,明智的做法是确保Product有一个equals方法可以检查与比较代码相同的属性。

于 2012-11-24T21:48:30.580 回答