簡體   English   中英

決定使用可比或比較器

[英]Deciding to use Comparable or Comparator

我的程序實現了一個Product類,其對象包含以下實例變量: nameprioritypriceamount

我有一個LinkedListProduct ,我需要在做任何其他操作之前進行排序對象LinkedList

我想按優先順序(從最低到最高)對列表進行排序。 如果優先級相同,則查看價格(從最低到最高),然后查看名稱(字母順序)。

我已經閱讀了很多有關Collections.sortComparableComparator 我相信我需要使用Comparable接口並實現compareTo方法。 我的想法是,因為prioritypricename都具有“自然”的順序,所以使用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)。

有誰知道為什么我會收到此錯誤,並且可以指出正確的方向來解決它?

如果存在“自然”排序,請使用Comparable。 確定排序是否為“自然”的經驗法則是,對象的順序是否始終是這樣。

話雖如此,決定使用Comparable還是Camparator並不是您需要考慮太多的決定。 大多數IDE都有重構工具,這些工具使Comparable和Comparator之間的轉換非常容易。 因此,如果您現在選擇走錯誤的道路,那么進行更改將不需要太多的努力。

您在產品上定義的訂單非常具體,

  • 可能會在程序的將來版本中發生變化
  • 可能會因上下文參數化而豐富
  • 不會涵蓋新功能

因此,很難說它是“自然的”。

我建議定義一個常量,例如

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

那么您將可以輕松地在任何地方進行排序

Collections.sort(myProductList, Product.STANDARD_COMPARATOR);

當您添加其他比較器時,您的代碼將以更好的方式發展。

就像您通常應該更喜歡合成而不是繼承一樣,您應該嘗試避免以不可變的方式定義對象的行為。

如果您的訂單僅基於數字,那么“可Comparable就可以了。

但是,由於您的順序(有時)涉及文本的詞法順序,因此Comparator類更好,因為使用Comparable意味着使用String.compareTo會阻止您進行國際化。

實現Comparator單獨類可以利用本地化的Collator來比較String。 例如:

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方法,該方法檢查與比較代碼相同的屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM