Comparable和Comparator的區別

概要:

  Comparable和Comparator都是用於比較數據的大小的,實現Comparable接口須要重寫compareTo方法,實現Comparator接口須要重寫compare方法,這兩個方法的返回值都是int,用int類型的值來肯定比較結果,在Collections工具類中有一個排序方法sort,此方法能夠之傳一個集合,另外一個重載版本是傳入集合和比較器,前者默認使用的就是Comparable中的compareTo方法,後者使用的即是咱們傳入的比較器Comparator,java的不少類已經實現了Comparable接口,好比說String,Integer等類,而咱們其實也是基於這些實現了Comparator或者Comparab接口的原生類來比較咱們本身的類,好比說自定義一個類User,屬性有name和age,倆個user之間的比較無非就是比較name和age的大小。java

Comparable:

  Comparable接口中只有一個方法:ide

public int compareTo(T o);

  調用此方法的對象,也就是this和o進行比較,若返回值大於0則this大於o,返回值等於0則是this等於o,返回值小於0則是this<o,而這個Comparable是直接在咱們的自定義類User上實現,由於this是須要一個明確的比較對象的,也就是通常狀況下咱們會在定義User類的時候有排序的需求,就要實現此接口。工具

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

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

    public UserComparable(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "UserComparable{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public int compareTo(UserComparable o) {
        if (this.name.compareTo(o.name)==0){
            if (this.age == o.age){
                return 0;
            }else if (this.age >o.age){
                return 1;
            }else {
                return -1;
            }
        }else if (this.name.compareTo(o.name)>0){
            return 1;
        }else {
            return -1;
        }
    }

    public static void main(String[] args) {
        List<UserComparable> list = new ArrayList<UserComparable>();
        list.add(new UserComparable("gol",21));
        list.add(new UserComparable("gol",19));
        list.add(new UserComparable("xiao",21));
        list.add(new UserComparable("long",21));
        System.out.println("排序前:"+list);
        //排序規則:先按name排序,若name相等則再比較age
        Collections.sort(list);
        System.out.println("排序後:"+list);
    }
}

  輸出結果爲:this

    排序前:[UserComparable{name='gol', age=21}, UserComparable{name='gol', age=19}, UserComparable{name='xiao', age=21}, UserComparable{name='long', age=21}]
    排序後:[UserComparable{name='gol', age=19}, UserComparable{name='gol', age=21}, UserComparable{name='long', age=21}, UserComparable{name='xiao', age=21}]spa

Comparator:

  Comparator接口中方法不少,可是咱們只須要實現一個,也是最重要的一個compare,也許有的人會好奇爲何接口中的方法能夠不用實現,由於這是JDK8之後的新特性,在接口中用default修飾的方法能夠有方法體,在實現接口的時候能夠不用重寫,能夠類比抽象類。設計

  

int compare(T o1, T o2);

  compare比較的o1和o2,返回值大於0則o1大於o2,依次類推,對於compare;來講this是誰不重要,所比較的兩個對象都已經傳入到方法中,全部Comparator就是有個外部比較器,在咱們設計User初時,並不須要它有比較功能,在後期擴展業務是,Comparator的存在可使咱們在不修改源代碼的狀況下來完成需求,只須要新定義一個比較器來實現Comparator,重寫compare方法並將User對象傳進去。code

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class User {
    private String name;
    private int age;

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

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public static void main(String[] args) {
        List<User> list = new ArrayList<User>();
        list.add(new User("gol", 21));
        list.add(new User("gol", 19));
        list.add(new User("xiao", 21));
        list.add(new User("long", 21));
        System.out.println("排序前:" + list);
        //排序規則:先按name排序,若name相等則再比較age
        //建立比較器對象
        Comparator comparator = new UserComparator();
        Collections.sort(list,comparator);
        System.out.println("排序後:" + list);
    }

    static class UserComparator implements Comparator<User> {

        @Override
        public int compare(User o1, User o2) {
            if (o1.name.compareTo(o2.name) == 0) {
                if (o1.age == o2.age) {
                    return 0;
                } else if (o1.age > o2.age) {
                    return 1;
                } else {
                    return -1;
                }
            } else if (o1.name.compareTo(o2.name) > 0) {
                return 1;
            } else {
                return -1;
            }
        }
    }
}

  輸出結果爲:  對象

    排序前:[User{name='gol', age=21}, User{name='gol', age=19}, User{name='xiao', age=21}, User{name='long', age=21}]
    排序後:[User{name='gol', age=19}, User{name='gol', age=21}, User{name='long', age=21}, User{name='xiao', age=21}]blog

結論:

  java中大部分咱們經常使用的數據類型的類都實現了Comparable接口,而僅僅只有一個抽象類RuleBasedCollator實現了Comparator接口 ,仍是咱們不經常使用的類,這並非要用Comparab而不要使用Comparator,在設計初時有需求就選擇Comparable,若後期須要擴展或增長排序需求是,再增長一個比較器Comparator,畢竟能寫Collections.sort(arg1),沒人樂意寫Collections.sort(arg1,arg2)。排序

相關文章
相關標籤/搜索