1. 程式人生 > >java常用類——比較器

java常用類——比較器

class Apple implements Comparable<Apple>{

    int id;

    double price;

 

    public Apple(int id, double price) {

        this.id = id;

        this.price = price;

    }

    public int compareTo(Apple o) {

        //return Double.compare(this.getPrice(),o.getPrice());

        if (Math.abs(this.price-o.price)<0.001)

            return 0;

        else

            return (o.price-this.price)>0?1:-1;

    }

    @Override

    public String toString() {

        return "Apple{" +

                "id=" + id +

                ", price=" + price +

                '}';

    }

}

class AESComparator implements Comparator<Apple>{

 

    public int compare(Apple o1, Apple o2) {

        if (Math.abs(o1.price-o2.price)<0.001)

            return 0;

        else{

            return (o1.price-o2.price)>0?1:-1;

        }

    }

}

 實現了Comparable介面的類需要實現compareTo()方法,傳入一個外部引數進行比對,實現了Comparator介面的方法需要實現compare()方法,對外部傳入的兩個類進行比較,從而讓外部方法在比較時呼叫。

 兩者的區別是實現Comparator介面程式碼更加靈活,可以定義某個類的多個比較器,從而在排序時根據實際場景自由呼叫,而Comparable介面實現後便不能改動。

 總結:

comparator介面:真正要實現的只有compare()方法,需要單獨準備出一個類來實現comparator介面,這個類將作為指定類的排序類

public int compare(Emp o1,Emp,o2){

     return o1.id - o2.id

}

這是說如果o1的id - o2的id是正數就升序,如果負數降序。如果0就剔除

>=1  升序

<=-1 降序

=0 重複,不記錄

comparable介面

實現該類介面不需要重新建立一個排序的類,使用介面compareble介面排序,只要重寫裡面的compareTo()方法

Collections類是一個包裝類,它包含有各種有關集合操作的靜態方法。就像一個工具類。

Collections.sort()

sort()排序方法,根據元素的自然排序對指定列表按升序進行排序

public static <T>void sort(List<T> list,Comparator<>),根據指定比較器產生的順序對指定列表進行排序,此列表內的所有元素都必須可使用指定的比較器相互比較

引數:list——要排序的列表

          C——確定列表順序的比較器

在Java中經常會涉及到物件陣列的排序問題,那麼就涉及到物件之間的比較問題。

通常物件之間的比較可以從兩個方面去看:

第一個方面:物件的地址是否一樣,也就是是否引用自同一個物件。這種方式可以直接使用“==“來完成。

第二個方面:以物件的某一個屬性的角度去比較。

從最新的JDK8而言,有三種實現物件比較的方法:

一、覆寫Object類的equals()方法;

二、繼承Comparable介面,並實現compareTo()方法;

三、定義一個單獨的物件比較器,繼承自Comparator介面,實現compare()方法。

由於使用的排序方式的不同,具體選擇哪種方法來實現物件的比較也會有所不同。

覆寫equals()方法,一般用於自己實現物件陣列排序的情況,而對於要使用java內建的排序演算法時,使用後面兩種方式都是可行的。

先來看第二種方式,這種方式就是讓自己編寫的類繼承Comparable介面,並實現compareTo()方法,這種情況下,在使用java.util.Arrays.sort()

方法時,不用指定具體的比較器,sort()方法會使用物件自己的比較函式來完成物件的排序。下面是一個具體的例子:

[java] view plain copy

import java.util.Arrays;  

class BookCook implements Comparable<BookCook>{  

    private String title;  

    private double price;  

    public BookCook(String title,double price){  

        this.title = title;  

        this.price = price;  

    }  

    @Override  

    public String toString() {  

        return "書名:"+this.title+",價格:"+this.price;  

    }  

    @Override  

    public int compareTo(BookCook o) {  

        if(this.price > o.price){  

            return 1;  

        }else if(this.price < o.price){  

            return -1;  

        }else{  

            return 0;  

        }  

    }  

}  

一般我們使用以上兩種方法就能夠滿足實際的開發問題。但是當出現以下情況時,就需要用到Comparator介面:

要在已經開發好的程式碼的基礎上完善物件的比較功能時,又不想更改之前的程式碼,這種情況下,從JDK1.8之後出現了Comparator介面,是對這種情況的一個彌補。

這種情況下,我們需要單獨定義一個物件比較器,繼承Comparator介面,並實現compare()方法。示例程式碼如下:

[java] view plain copy

class Student {  

    private String name;  

    private double score;  

    public Student(String name,double score){  

        this.name = name;  

        this.score = score;  

    }  

    public double getScore(){  

        return this.score;  

    }  

    @Override  

    public String toString() {  

        return "姓名:"+this.name+",分數:"+this.score;  

    }    

}  

class StudentComparator implements Comparator<Student> {  

    @Override  

    public int compare(Student o1,Student o2) {  

        if(o1.getScore() > o2.getScore()){  

            return 1;  

        }else if(o1.getScore() < o2.getScore()){  

            return -1;  

        }else{  

            return 0;  

        }  

    }  

}  

public class TestComparator {  

    public static void main(String[] args) {  

        Student[] sts = new Student[]{  

                new Student("小戴",60),  

                new Student("小王",90),  

                new Student("老王",80),  

                new Student("小萱",95)  

        };    

        java.util.Arrays.sort(sts, new StudentComparator());  

        System.out.println(java.util.Arrays.toString(sts));  

    }  

}  

Java中存在比較運算子:> 、< 、>=、<=、!=、==、instanceof

只能比較基本資料型別,如果對於物件無法進行比較,如果在物件中需要實現物件之間的比較,只能通過Comparable、Compartor介面實現

(1) Comparable介面(自然排序)

String、包裝類都已經預設實現了Comparable介面,並重寫了int compareTo(T o)方法(定義排序規則),所以String、包裝類都是可以進行排序的

預設是按照升序進行排序的

int compareTo(T o)

如果返回值是正數,代表呼叫者(this)的值比o的值要大

如果返回值是負數,代表呼叫者(this)的值比o的值要小

如果返回值是0,代表呼叫者(this)的值比o的值相等

如果一個自定義類需要實現外匯返傭http://www.fx61.com/排序功能,需要讓當前類實現Comparable介面,重寫int compareTo(T o)方法,在該方法中重寫排序的規則

如果一個類一旦實現了Comparable介面,那麼這個類的物件在任意地方都可以進行排序或者比較

/*

String、包裝類都已經預設實現了Comparable介面,並重寫了int compareTo(T o)方法

*/

public class CompareDemo {

public static void main(String[] args) {

int[] arr = {5,4,2,1,3};

Arrays.sort(arr);

System.out.println(Arrays.toString(arr));

 

String[] s = {"AA","CC","ZZ","BB","JJ"};

Arrays.sort(s);

System.out.println(Arrays.toString(s));

}

}

/*

物件之間比較

*/

public class CompareDemo {

public static void main(String[] args) {

Employee[] e = new Employee[5];

e[0] = new Employee("e001","Jack","d001");

e[1] = new Employee("e005","Tom","d010");

e[2] = new Employee("e010","Jack","d011");

e[3] = new Employee("e004","Rose","d005");

e[4] = new Employee("e009","Marry","d008");

Arrays.sort(e);

System.out.println(Arrays.toString(e));

}

}

class Employee implements Comparable<Employee>{

private String eno;

private String ename;

private String dept;

public String getEno() {

return eno;

}

public void setEno(String eno) {

this.eno = eno;

}

public String getEname() {

return ename;

}

public void setEname(String ename) {

this.ename = ename;

}

public String getDept() {

return dept;

}

public void setDept(String dept) {

this.dept = dept;

}

public Employee(String eno, String ename, String dept) {

super();

this.eno = eno;

this.ename = ename;

this.dept = dept;

}

public Employee() {

super();

}

@Override

public String toString() {

return "Employee [eno=" + eno + ", ename=" + ename + ", dept=" + dept + "]";

}

@Override

public int compareTo(Employee o) {

//藉助String的compareTo方法

return this.eno.compareTo(o.eno);

}

}

(2)Comparator介面(定製排序)

如果一個類沒有實現Comparable介面,但是這個類又不方便實現Comparable介面(開閉原則),或者一個類已經實現了Comparable介面,但是其中的compareTo不滿足我們的需求,那麼我們可以使用Comparator介面方式進行定製排序

預設升序

int compare(T o1,T o2)

o1>o2 返回正數

o1<o2 返回負數

o1==o2 返回0

public class CompareDemo {

public static void main(String[] args) {

Employee[] e = new Employee[5];

e[0] = new Employee("e001","Jack","d001");

e[1] = new Employee("e003","Tom","d010");

e[2] = new Employee("e003","Jack","d011");

e[3] = new Employee("e004","Rose","d005");

e[4] = new Employee("e002","Marry","d008");

Arrays.sort(e, new Comparator<Employee>() {

@Override

public int compare(Employee o1, Employee o2) {

if(o1.getEno().compareTo(o2.getEno())!=0) {

return o1.getEno().compareTo(o2.getEno());

}else {

return -o1.getEname().compareTo(o2.getEname());

}

}

});

System.out.println(Arrays.toString(e));

}

}

class Employee {

private String eno;

private String ename;

private String dept;

public String getEno() {

return eno;

}

public void setEno(String eno) {

this.eno = eno;

}

public String getEname() {

return ename;

}

public void setEname(String ename) {

this.ename = ename;

}

public String getDept() {

return dept;

}

public void setDept(String dept) {

this.dept = dept;

}

public Employee(String eno, String ename, String dept) {

super();

this.eno = eno;

this.ename = ename;

this.dept = dept;

}

public Employee() {

super();

}

@Override

public String toString() {

return "Employee [eno=" + eno + ", ename=" + ename + ", dept=" + dept + "]";

}