我是java的新手,我并没有真正了解如何使用比较器接口。
我在ArrayList
班级和Item
班级中有Inventory
Item
个。
在我写的Item
课程中:
public class Item implements Comparator<Item> {
//stuff
...
@Override
public int compare(Item a, Item b) {
if (a.getID().compareToIgnoreCase(b.getID())>0)
return 1;
else if (a.getID().compareToIgnoreCase(b.getID())<0)
return -1;
else
return 0;
}
}
getID()方法只提供id,我必须使用它来对项目进行字母顺序排列。
我不确定这是不对的,它让我把@Override
注释,我不知道为什么。我还写了一个界面,只是说:
public interface Comparator<Item>
{
int compare(Item a, Item b);
}
我不确定那一点。另外,我如何实现此方法来对库存类中创建的arraylist进行排序?
谢谢,如果我的问题没有意义或需要澄清,请告诉我。
答案 0 :(得分:16)
编辑:首先,有几点:
@Override
注释不应是强制性的。如果Eclipse要你把它戴上,不要担心。import java.util.Comparator;
(在public class
之前)a)使用Java提供的版本和b)使代码与世界上存在的其他所有内容兼容。 Comparator接口不用于创建可以使自己按顺序排列的类。这是Comparable接口。
两者都相似,所以我将在这里描述。
正如您所知,Comparator界面有一种方法:compare
。比较器是通用的(使用尖括号<>
)并采用它将在<>
内比较的类型。问题是比较器用于比较其他类的项目。例如,我可以为java.lang.Integers
创建一个比较器,它返回“自然顺序”的反面(通常如何排序整数)。
比较器主要用于为其他对象提供一种在参数不按自然顺序排序时的方法。例如,java.util.TreeSet
class将比较器作为其排序功能。
可比较的目的是说可以比较一个物体。它也是通用的,并采用可与之比较的类型。例如,可以将Comparable<String>
与字符串进行比较。
Comparable有一种方法:compareTo()
。与比较器的compare()
不同,compareTo
采用一个参数。它的工作方式与compare
类似,不同之处在于它将调用对象用作一个参数。因此,comparableA.compareTo(comparableB)
与comparator.compare(comparableA, comparableB)
相同。
可比较主要建立对象的自然顺序,并且是比较对象的默认方式。比较器的作用是当人们对数据比较或排序有不同需求时覆盖这种自然顺序。
要对List
进行排序,您可以使用现有方法:向下滚动至java.util.Collections
class上的sort
。一种方法需要比较器,另一种方法不需要。 sort
是静态的;使用Collections.sort(...)
,而不是Collections c = new Collections(); c.sort(...)
。 (Collections
无论如何都没有构造函数,所以 meh 。)
答案 1 :(得分:11)
要使用Comparator接口,您必须实现它并将其作为匿名类传递给Collections.sort(List list, Comparator c)作为第二个参数。
如果您只想将列表传递给Collections.sort(List list),那么您的Item
类必须使用工具Comparable界面。
因此,在这两种情况下,Collections.sort
方法都知道如何对列表中的元素进行排序
这是一些示例代码:
项目类实施Comparable
+库存项目列表
public class Item implements Comparable<Item> {
String id = null;
public Item(String id) {
this.id = id;
}
@Override
public String toString() {
return id;
}
@Override
public int compareTo(Item o) {
return - id.compareToIgnoreCase(o.id);
}
}
public class Inventory {
List<Item> items = new ArrayList<>();
public void addItem(Item item) {
items.add(item);
}
public static void main(String[] args) {
Inventory inventory = new Inventory();
inventory.addItem(new Item("2"));
inventory.addItem(new Item("4"));
inventory.addItem(new Item("1"));
inventory.addItem(new Item("7"));
Collections.sort(inventory.items, new Comparator<Item>() {
@Override
public int compare(Item o1, Item o2) {
return o1.id.compareToIgnoreCase(o2.id);
}
});
System.out.println(inventory.items);
Collections.sort(inventory.items);
System.out.println(inventory.items);
}
}
<强>输出强>
[1, 2, 4, 7] // ascending
[7, 4, 2, 1] // descending since the compareTo method inverts the sign of the comparison result.
答案 2 :(得分:3)
您正在混合接口Comparator
和Comparable
。
比较者:http://docs.oracle.com/javase/6/docs/api/java/util/Comparator.html
可比较:http://docs.oracle.com/javase/6/docs/api/java/lang/Comparable.html
Comparator的目的是一个类(在现场匿名声明或以其他方式声明),可以传递给需要排序的操作,并定义将在项目上使用的排序。 比较器将在需要排序的类的OUTSIDE中使用,如果有另一种方法要对其进行排序。
Comparable的目的是说类(实现Comparable)具有自然顺序 - 这就是它的本质。 如果您需要排序的类具有自然排序,则将其定义为Comparable。(实现Comparable排序顺序的类仍然可以被Comparator覆盖。另一方面,如果类不是与通过比较器相比,强制要求订购是可能的。)
答案 3 :(得分:0)
您已经实现了错误的界面,您需要Comparable
答案 4 :(得分:0)
使用 @Override 注释是eclipse,netbeans等编辑器中的标准做法,用于通知开发人员他正在重写/实现父类/接口方法。这是可选的。
不要在Item类中实现此接口。创建 new 类并实现Comparator
接口。
public class ItemCompare implements Comparator<Item> {
@Override
public int compare(Item a, Item b) {
if (a.getID().compareToIgnoreCase(b.getID())>0)
return 1;
else if (a.getID().compareToIgnoreCase(b.getID())<0)
return -1;
return 0;
}
}
然后,在你的主要课程中,这样做:
ArrayList al = new ArrayList<Item>
Collections.sort(al, new ItemCompare())