[英]Deciding to use Comparable or Comparator
我的程序實現了一個Product
類,其對象包含以下實例變量: name
, priority
, price
和amount
。
我有一個LinkedList
的Product
,我需要在做任何其他操作之前進行排序對象LinkedList
。
我想按優先順序(從最低到最高)對列表進行排序。 如果優先級相同,則查看價格(從最低到最高),然后查看名稱(字母順序)。
我已經閱讀了很多有關Collections.sort
, Comparable
和Comparator
。 我相信我需要使用Comparable
接口並實現compareTo
方法。 我的想法是,因為priority
, price
和name
都具有“自然”的順序,所以使用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.