Java中Comparable与Comparator的区别以及PriorityQueue的使用
Java中有两种方式来提供比较功能。
Comparable
实现java.lang.Comparable接口,使你的类天生具有比较的能力,此接口很简单,只有一个compareTo方法。
此方法接收另一个Object为参数,如果当前对象小于参数则返回负值,如果相等则返回零,否则返回正值。
以x.compareTo(y)为例,若返回“负数”,意味着“x比y小”,返回“零”,意味着“x等于y”,返回“正数”,意味着“x大于y”。
示例:
class Person implements Comparable{
@Override
public int compareTo(Person person) {
return name.compareTo(person.name);
//return this.name - person.name;
}
}
ArrayList list = new ArrayList();
// 添加对象到ArrayList中
list.add(new Person("aaa", 10));
list.add(new Person("bbb", 20));
list.add(new Person("ccc", 30));
list.add(new Person("ddd", 40));
Collections.sort(list); //这里会自动调用Person中重写的compareTo方法。
Comparator
定义一个类去实现Comparator接口,重写其中的compare方法。
示例:
public class ComparatorDemo {
public static void main(String[] args) {
List people = Arrays.asList(
new Person("Joe", 24),
new Person("Pete", 18),
new Person("Chris", 21)
);
Collections.sort(people, new MyComparator ());
System.out.println(people);
//[{name=Chris, age=21}, {name=Joe, age=24}, {name=Pete, age=18}]
Collections.sort(people, new Comparator() {
@Override
public int compare(Person a, Person b) {
// TODO Auto-generated method stub
return a.age < b.age ? -1 : a.age == b.age ? 0 : 1;
}
});
System.out.println(people);
//[{name=Pete, age=18}, {name=Chris, age=21}, {name=Joe, age=24}]
}
}
class MyComparator implements Comparator {
@Override
public int compare(Person a, Person b) {
return a.name.compareToIgnoreCase(b.name);
}
}
class Person {
String name;
int age;
Person(String n, int a) {
name = n;
age = a;
}
@Override
public String toString() {
return String.format("{name=%s, age=%d}", name, age);
}
}
PriorityQueue
PriorityQueue需要传入Comparator, 决定优先队列是大顶堆还是小顶堆,其原理是通过compare方法判断建堆时哪个元素上升。
//对于最大堆,当x>e时,让x上升,则 x>e时返回负数,即
int compare(Integer x, Integer e){
return x > e ? -1 : 1;
}
//对于最小堆,当x
示例:
// 最小优先队列,直接 return o1.compareTo(o2);
PriorityQueue queue = new PriorityQueue(new Comparator(){
@Override
public int compare(Integer o1, Integer o2){
return o1 < o2 ? -1 : 1;
/* e.g., return o1.compare(o2); */
}
});
// 最大优先队列,则反过来 return o2.compareTo(o1);