Comparable 簡(jiǎn)介
Comparable 是排序接口。
若一個(gè)類(lèi)實(shí)現(xiàn)了Comparable接口,就意味著“該類(lèi)支持排序”。即然實(shí)現(xiàn)Comparable接口的類(lèi)支持排序,假設(shè)現(xiàn)在存在“實(shí)現(xiàn)Comparable接口的類(lèi)的對(duì)象的List列表(或數(shù)組)”,則該List列表(或數(shù)組)可以通過(guò) Collections.sort(或 Arrays.sort)進(jìn)行排序。
此外,“實(shí)現(xiàn)Comparable接口的類(lèi)的對(duì)象”可以用作“有序映射(如TreeMap)”中的鍵或“有序集合(TreeSet)”中的元素,而不需要指定比較器。
Comparable 定義
Comparable 接口僅僅只包括一個(gè)函數(shù),它的定義如下:
package java.lang;importjava.util.*;
publicinterfaceComparable {
? ? public int compareTo(T o);
}
說(shuō)明:
假設(shè)我們通過(guò) x.compareTo(y) 來(lái)“比較x和y的大小”。若返回“負(fù)數(shù)”,意味著“x比y小”;返回“零”,意味著“x等于y”;返回“正數(shù)”,意味著“x大于y”。
Comparator 簡(jiǎn)介
Comparator 是比較器接口。
我們?nèi)粜枰刂颇硞€(gè)類(lèi)的次序,而該類(lèi)本身不支持排序(即沒(méi)有實(shí)現(xiàn)Comparable接口);那么,我們可以建立一個(gè)“該類(lèi)的比較器”來(lái)進(jìn)行排序。這個(gè)“比較器”只需要實(shí)現(xiàn)Comparator接口即可。
也就是說(shuō),我們可以通過(guò)“實(shí)現(xiàn)Comparator類(lèi)來(lái)新建一個(gè)比較器”,然后通過(guò)該比較器對(duì)類(lèi)進(jìn)行排序。
Comparator 定義
Comparator 接口僅僅只包括兩個(gè)個(gè)函數(shù),它的定義如下:
package java.util;
public interface Comparator<T> {
? ? int compare(T o1, T o2);
? ? boolean equals(Object obj);
}
實(shí)例
import java.util.*;
import java.lang.Comparable;
/**
* @desc "Comparator"和“Comparable”的比較程序。
*? (01) "Comparable"
*? 它是一個(gè)排序接口,只包含一個(gè)函數(shù)compareTo()。
*? 一個(gè)類(lèi)實(shí)現(xiàn)了Comparable接口,就意味著“該類(lèi)本身支持排序”,它可以直接通過(guò)Arrays.sort() 或 Collections.sort()進(jìn)行排序。
*? (02) "Comparator"
*? 它是一個(gè)比較器接口,包括兩個(gè)函數(shù):compare() 和 equals()。
*? 一個(gè)類(lèi)實(shí)現(xiàn)了Comparator接口,那么它就是一個(gè)“比較器”。其它的類(lèi),可以根據(jù)該比較器去排序。
*
*? 綜上所述:Comparable是內(nèi)部比較器,而Comparator是外部比較器。
*? 一個(gè)類(lèi)本身實(shí)現(xiàn)了Comparable比較器,就意味著它本身支持排序;若它本身沒(méi)實(shí)現(xiàn)Comparable,也可以通過(guò)外部比較器Comparator進(jìn)行排序。
*/
public class CompareComparatorAndComparableTest{
? ? public static void main(String[] args) {
? ? ? ? // 新建ArrayList(動(dòng)態(tài)數(shù)組)
? ? ? ? ArrayList<Person> list = new ArrayList<Person>();
? ? ? ? // 添加對(duì)象到ArrayList中
? ? ? ? list.add(new Person("ccc", 20));
? ? ? ? list.add(new Person("AAA", 30));
? ? ? ? list.add(new Person("bbb", 10));
? ? ? ? list.add(new Person("ddd", 40));
? ? ? ? // 打印list的原始序列
? ? ? ? System.out.printf("Original? sort, list:%s\n", list);
? ? ? ? // 對(duì)list進(jìn)行排序
? ? ? ? // 這里會(huì)根據(jù)“Person實(shí)現(xiàn)的Comparable<String>接口”進(jìn)行排序,即會(huì)根據(jù)“name”進(jìn)行排序
? ? ? ? Collections.sort(list);
? ? ? ? System.out.printf("Name? ? ? sort, list:%s\n", list);
? ? ? ? // 通過(guò)“比較器(AscAgeComparator)”,對(duì)list進(jìn)行排序
? ? ? ? // AscAgeComparator的排序方式是:根據(jù)“age”的升序排序
? ? ? ? Collections.sort(list, new AscAgeComparator());
? ? ? ? System.out.printf("Asc(age)? sort, list:%s\n", list);
? ? ? ? // 通過(guò)“比較器(DescAgeComparator)”,對(duì)list進(jìn)行排序
? ? ? ? // DescAgeComparator的排序方式是:根據(jù)“age”的降序排序
? ? ? ? Collections.sort(list, new DescAgeComparator());
? ? ? ? System.out.printf("Desc(age) sort, list:%s\n", list);
? ? ? ? // 判斷兩個(gè)person是否相等
? ? ? ? testEquals();
? ? }
? ? /**
? ? * @desc 測(cè)試兩個(gè)Person比較是否相等。
? ? *? 由于Person實(shí)現(xiàn)了equals()函數(shù):若兩person的age、name都相等,則認(rèn)為這兩個(gè)person相等。
? ? *? 所以,這里的p1和p2相等。
? ? *
? ? *? TODO:若去掉Person中的equals()函數(shù),則p1不等于p2
? ? */
? ? private static void testEquals() {
? ? ? ? Person p1 = new Person("eee", 100);
? ? ? ? Person p2 = new Person("eee", 100);
? ? ? ? if (p1.equals(p2)) {
? ? ? ? ? ? System.out.printf("%s EQUAL %s\n", p1, p2);
? ? ? ? } else {
? ? ? ? ? ? System.out.printf("%s NOT EQUAL %s\n", p1, p2);
? ? ? ? }
? ? }
? ? /**
? ? * @desc Person類(lèi)。
? ? *? ? ? Person實(shí)現(xiàn)了Comparable接口,這意味著Person本身支持排序
? ? */
? ? private static class Person implements Comparable<Person>{
? ? ? ? int age;
? ? ? ? String name;
? ? ? ? public Person(String name, int age) {
? ? ? ? ? ? this.name = name;
? ? ? ? ? ? this.age = age;
? ? ? ? }
? ? ? ? public String getName() {
? ? ? ? ? ? return name;
? ? ? ? }
? ? ? ? public int getAge() {
? ? ? ? ? ? return age;
? ? ? ? }
? ? ? ? public String toString() {
? ? ? ? ? ? return name + " - " +age;
? ? ? ? }
? ? ? ? /**
? ? ? ? * 比較兩個(gè)Person是否相等:若它們的name和age都相等,則認(rèn)為它們相等
? ? ? ? */
? ? ? ? boolean equals(Person person) {
? ? ? ? ? ? if (this.age == person.age && this.name == person.name)
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? return false;
? ? ? ? }
? ? ? ? /**
? ? ? ? * @desc 實(shí)現(xiàn) “Comparable<String>” 的接口,即重寫(xiě)compareTo<T t>函數(shù)。
? ? ? ? *? 這里是通過(guò)“person的名字”進(jìn)行比較的
? ? ? ? */
? ? ? ? @Override
? ? ? ? public int compareTo(Person person) {
? ? ? ? ? ? return name.compareTo(person.name);
? ? ? ? ? ? //return this.name - person.name;
? ? ? ? }
? ? }
? ? /**
? ? * @desc AscAgeComparator比較器
? ? *? ? ? 它是“Person的age的升序比較器”
? ? */
? ? private static class AscAgeComparator implements Comparator<Person> {
? ? ? ? @Override
? ? ? ? public int compare(Person p1, Person p2) {
? ? ? ? ? ? return p1.getAge() - p2.getAge();
? ? ? ? }
? ? }
? ? /**
? ? * @desc DescAgeComparator比較器
? ? *? ? ? 它是“Person的age的升序比較器”
? ? */
? ? private static class DescAgeComparator implements Comparator<Person> {
? ? ? ? @Override
? ? ? ? public int compare(Person p1, Person p2) {
? ? ? ? ? ? return p2.getAge() - p1.getAge();
? ? ? ? }
? ? }
}
運(yùn)行程序,輸出如下:
Original? sort, list:[ccc - 20, AAA - 30, bbb - 10, ddd - 40]
Name? ? ? sort, list:[AAA - 30, bbb - 10, ccc - 20, ddd - 40]
Asc(age)? sort, list:[bbb - 10, ccc - 20, AAA - 30, ddd - 40]
Desc(age) sort, list:[ddd - 40, AAA - 30, ccc - 20, bbb - 10]
eee - 100 EQUAL eee - 100