Java中Comparable與Comparator的區別以及PriorityQueue的使用
阿新 • • 發佈:2021-10-17
Java中有兩種方式來提供比較功能。
Comparable
實現java.lang.Comparable介面,使你的類天生具有比較的能力,此介面很簡單,只有一個compareTo方法。
此方法接收另一個Object為引數,如果當前物件小於引數則返回負值,如果相等則返回零,否則返回正值。
以x.compareTo(y)為例,若返回“負數”,意味著“x比y小”,返回“零”,意味著“x等於y”,返回“正數”,意味著“x大於y”。
示例:
class Person implements Comparable<Person>{ @Override public int compareTo(Person person) { return name.compareTo(person.name); //return this.name - person.name; } } ArrayList<Person> list = new ArrayList<Person>(); // 新增物件到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<Person> 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<Person>() { @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<Person> { @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<e時,讓compare(x, e) < 0,即 int compare(Integer x, Integer e){ return x < e ? -1 : 1; // return x.compareTo(e); }
示例:
// 最小優先佇列,直接 return o1.compareTo(o2);
PriorityQueue<Integer> queue = new PriorityQueue<Integer>(new Comparator<Integer>(){
@Override
public int compare(Integer o1, Integer o2){
return o1 < o2 ? -1 : 1;
/* e.g., return o1.compare(o2); */
}
});
// 最大優先佇列,則反過來 return o2.compareTo(o1);