Comparable接口與Comparator接口

Comparable接口與Comparator接口

關於如何比較兩個對象的大小問題,JDK提供了兩個接口java.lang.Comparablejava.util.Comparatorhtml

天然排序:java.lang.Comparable

Comparable接口只提供了一個方法:java

public interface Comparable<T> {
	public int compareTo(T o);
}

該接口的返回值是int:若是是正數,表示當前對象比o大;若是是負數,表示當前對象小於o;若是爲0,表示二者相等。數組

下面是一個實現了Comparable接口的Employee類,及測試代碼測試

package com.company.employee;

public class Employee implements Comparable<Employee> {
    private int empId;
    private String name;
    private int age;

    public Employee(int empId, String name, int age) {
        this.empId = empId;
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public int getEmpId() {

        return empId;
    }

    /**
     * Compare a given Employee with this object.
     * If employee id of this object is
     * greater than the received object,
     * then this object is greater than the other.
     */
    public int compareTo(Employee o) {
        return this.empId - o.empId;
    }
}

package com.company.employee;

import java.util.ArrayList;
import java.util.List;

public class Util {
    public static List<Employee> getEmployees() {
        List<Employee> col = new ArrayList<Employee>();

        col.add(new Employee(5, "Frank", 28));
        col.add(new Employee(1, "Jorge", 19));
        col.add(new Employee(6, "Bill", 34));
        col.add(new Employee(3, "Michel", 10));
        col.add(new Employee(7, "Simpson", 8));
        col.add(new Employee(4, "Clerk",16 ));
        col.add(new Employee(8, "Lee", 40));
        col.add(new Employee(2, "Mark", 30));

        return col;
    }
}

package com.company.employee;

import java.util.Collections;
import java.util.List;

public class TestEmployeeSort {
    public static void main(String[] args) {
        List coll = Util.getEmployees();
        Collections.sort(coll);		// sort method
        printList(coll);
    }

    private static void printList(List<Employee> list) {
        System.out.println("EmpId\tName\tAge");
        for (Employee e: list) {
            System.out.println(e.getEmpId() + "\t" + e.getName() + "\t" + e.getAge());
        }
    }
}

實現了java.lang.Comparable接口後,就能夠使用java.util.Collections.sort(List)java.util.Arrays.sort(Object[])這兩個方法來對一組對象(列表或數組)來進行排序,如上面的例子中所示。調用sort方法進行排序時,在比較兩個對象的大小時,就會調用對象的CompareTo方法來進行判斷。上面的例子中,就會按照屬性empId進行排序。this

比較器排序:java.util.Comparator

但上面的實現有個問題:因爲比較策略與類綁定了,所以咱們只能按照屬性empId來對Employee對象來進行排序。若是要使用其餘屬性來進行排序,那咱們就不得不修改Employee類中的compareTo方法。但不管怎樣,咱們都只能有一種排序規則。此時,比較器Comparator就起做用了。code

實現Comparator接口只須要實現其中的compare方法:htm

int compare(T o1, T o2);

經過實現一個比較器類Comparator,咱們在不更改原類(Employee)的前提下,就能夠按照不一樣的規則來進行比較。如按照名字進行比較的示例代碼以下對象

package com.company.employee;

import java.util.Comparator;

public class EmpSortByName implements Comparator<Employee> {
    public int compare(Employee o1, Employee o2) {
        return o1.getName().compareTo(o2.getName());
    }
}

package com.company.employee;

import java.util.Collections;
import java.util.List;

public class TestEmployeeSort {
    public static void main(String[] args) {
        List coll = Util.getEmployees();
        // Collections.sort(coll);		// sort method
        Collections.sort(coll, new EmpSortByName());
        printList(coll);
    }

    private static void printList(List<Employee> list) {
        System.out.println("EmpId\tName\tAge");
        for (Employee e: list) {
            System.out.println(e.getEmpId() + "\t" + e.getName() + "\t" + e.getAge());
        }
    }
}

如上代碼所示,咱們能夠傳遞一個比較器對象給sort方法,在比較兩個對象的大小時,sort方法就會調用比較器對象的compare()方法來進行比較。排序

總結

  1. Comparable接口位於java.lang包下,Comparator接口位於java.util包下
  2. Comparable將比較代碼(規則)嵌入在類自身的代碼中,只提供一種規則。Comparator是一個比較器,能夠在另外一個獨立的類中定義比較規則,能夠經過提供多個比較器類提供多種比較規則
  3. 若是沒法修改原類,又想要實現排序,則只能提供額外的比較器對象Comparator
  4. 實現了Comparable接口,能夠調用java.util.Collections.sort(List)java.util.Arrays.sort(Object[])這兩個方法來進行排序;經過提供Comparator對象,能夠調用java.util.Collections.sort(List<T> list, Comparator<? super T> c)java.util.Arrays.sort(T[] a, Comparator<? super T> c)來進行排序

代碼參考接口

相關文章
相關標籤/搜索