[英]Deciding to use Comparable or Comparator
My program implements a Product
class whose objects contain the following instance variables: name
, priority
, price
, and amount
. 我的程序实现了一个Product
类,其对象包含以下实例变量: name
, priority
, price
和amount
。
I have a LinkedList
of Product
objects that I need to sort before doing any other operations on the LinkedList
. 我有一个LinkedList
的Product
,我需要在做任何其他操作之前进行排序对象LinkedList
。
I want to sort the list first by priority (from lowest to highest). 我想按优先顺序(从最低到最高)对列表进行排序。 If priority is the same, then look at the price (lowest to highest), then the name (alphabetical order). 如果优先级相同,则查看价格(从最低到最高),然后查看名称(字母顺序)。
I have done a lot of reading about Collections.sort
, Comparable
, and Comparator
. 我已经阅读了很多有关Collections.sort
, Comparable
和Comparator
。 I believe I need to use the Comparable
interface and implement a compareTo
method. 我相信我需要使用Comparable
接口并实现compareTo
方法。 My thinking is that because both priority
, price
, and name
have a "natural" ordering it makes more sense to use Comparable
. 我的想法是,因为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)
}
Then when I want to sort my LinkedList I just call Collections.sort(LinkedList)
. 然后,当我想对LinkedList进行排序时,只需调用Collections.sort(LinkedList)
。 Before I start writing the code, can you tell me if I am I missing or forgetting anything? 在我开始编写代码之前,您能告诉我我是否想念还是忘记了什么吗?
** * ** * ** * **** UPDATE * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** * **** 更新 * ** * ** * ** * ** * ** * ** * ** * ** * ** * ** *
I just created a separate class called ProductComparator with a compare method. 我刚刚使用compare方法创建了一个单独的类ProductComparator。
This is part of the LinkedList class.. 这是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;
}
}
} }
I am getting the following error from the IDE when I compile. 编译时,我从IDE中收到以下错误。
The method sort(List, Comparator) in the type Collections is not applicable for the arguments (LinkedList, ProductComparator). 类型Collections中的方法sort(List,Comparator)不适用于参数(LinkedList,ProductComparator)。
Does anyone know why I am getting this error and can point me in the right direction to resolve it? 有谁知道为什么我会收到此错误,并且可以指出正确的方向来解决它?
If there is a "natural" ordering, use Comparable. 如果存在“自然”排序,请使用Comparable。 Rule of thumb for figuring out if the ordering is "natural" is, whether the order of the objects will always be that. 确定排序是否为“自然”的经验法则是,对象的顺序是否始终是这样。
Having said that, the decision whether to use Comparable or Camparator is not the kind of decision you need to think too much about. 话虽如此,决定使用Comparable还是Camparator并不是您需要考虑太多的决定。 Most IDEs have refactoring tools which makes the conversion between a Comparable and a Comparator very easy. 大多数IDE都有重构工具,这些工具使Comparable和Comparator之间的转换非常容易。 So if you choose to walk the wrong path now, changing that will not require too much effort. 因此,如果您现在选择走错误的道路,那么进行更改将不需要太多的努力。
The order you define here on your Product is very specific and 您在产品上定义的订单非常具体,
So it can hardly been said "natural". 因此,很难说它是“自然的”。
I'd suggest to define a constant, for example 我建议定义一个常量,例如
public static Comparator<Product> STANDARD_COMPARATOR = new Comparator<Product>() {
public int compare(Product p1, Product p1) {
return ...
}
};
then you'll be able to easily sort anywhere with 那么您将可以轻松地在任何地方进行排序
Collections.sort(myProductList, Product.STANDARD_COMPARATOR);
Your code will evolve in a better manner as you'll add other comparators. 当您添加其他比较器时,您的代码将以更好的方式发展。
Just like you should generally prefer composition over inheritance, you should try to avoid defining the behavior of your objects in immutable manner. 就像您通常应该更喜欢合成而不是继承一样,您应该尝试避免以不可变的方式定义对象的行为。
If your order was based only on numbers, Comparable
would be fine. 如果您的订单仅基于数字,那么“可Comparable
就可以了。
However, since your order (sometimes) involves lexical order of text, a Comparator
class is better, since use of Comparable
would mean using String.compareTo
which would prevent you from having internationalization. 但是,由于您的顺序(有时)涉及文本的词法顺序,因此Comparator
类更好,因为使用Comparable
意味着使用String.compareTo
会阻止您进行国际化。
A separate class which implements Comparator
can make use of a localized Collator
for comparing Strings. 实现Comparator
单独类可以利用本地化的Collator
来比较String。 For instance: 例如:
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;
}
}
Regardless of whether you go with Comparable or Comparator, it is wise to make sure Product
has an equals
method which checks the same attributes as the comparison code. 无论您使用Comparable还是Comparator,明智的做法是确保Product
具有一个equals
方法,该方法检查与比较代码相同的属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.