歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Java 中 Comparable 接口的意義和用法

在之前的文章中已經介紹了Java中Collection 接口和 Collections類. http://www.linuxidc.com/Linux/2016-12/138185.htm

一, 為何需要實現Comparable接口

我們知道Collections類中包含很多對實現Collection接口的容器各種操作的靜態方法.

當然, 其中最長用的莫過於排序了(Collections.sort(List l).

下面是1個簡單例子:

public class Compare1{
    public static void f(){
        ArrayList arr = new ArrayList();
        arr.add(10);
        arr.add(23);
        arr.add(7);

        System.out.println(arr);

        Collections.sort(arr);
       
        System.out.println(arr);
    }
}

邏輯很簡單, 就是在1個list容器中添加3個int數值(注意實際被自動裝箱成Interger對象).

正常輸出容器元素一次, 利用Collections.sort()方法排序後, 再輸出1次.

輸出:

  [java] [10, 23, 7]
  [java] [7, 10, 23]

但是當List容器添加的元素對象是屬於自己寫的類時, 就可能出問題了.

例子:

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

class Student{
    private String name;
    private int ranking;

    public Student(String name, int ranking){
        this.name = name;
        this.ranking = ranking;
    }

    public String toString(){
        return this.name + ":" + this.ranking;
    }
}

public class Compare2{
    public static void f(){
        ArrayList arr = new ArrayList();
        arr.add(new Student("Jack",10));
        arr.add(new Student("Bill",23));
        arr.add(new Student("Rudy",7));

        System.out.println(arr);
    }
}

上面定義了1個Student類, 它只有兩個成員, 名字和排名.

在f()方法內, 添加3個Student的對象到1個list容器中, 然後輸出(必須重寫String方法, 這裡不解釋了):

[java] [Jack:10, Bill:23, Rudy:7]

到此為止, 是沒有問題的.  但是當我對這個容器進行排序時就有問題了.

例如將上面的f()方法改成:

public class Compare2{
    public static void f(){
        ArrayList arr = new ArrayList();
        arr.add(new Student("Jack",10));
        arr.add(new Student("Bill",23));
        arr.add(new Student("Rudy",7));

        System.out.println(arr);
        Collections.sort(arr);
        System.out.println(arr);
    }
}

編譯時就會出錯:

 [java] Caused by: java.lang.ClassCastException: Collection_kng.Comparable_kng.Student cannot be cast to java.lang.Comparable

提示這個類Student沒有實現Comparable接口.

 

原因也很簡單, 因為Java不知道應該怎樣為Student對象排序, 是應該按名字排序? 還是按ranking來排序?

 

為什麼本文第1個例子就排序成功? 是因為Java本身提供的類Integer已經實現了Comparable接口. 也表明Integer這個類的對象是可以比較的.

 

而Student類的對象默認是不可以比較的.  除非它實現了Comparable接口.

 

總而言之,  如果你想1個類的對象支持比較(排序), 就必須實現Comparable接口.

 

二, Comparable接口簡介.

Comparable 接口內部只有1個要重寫的關鍵的方法.

就是

int compareTo(T o)

這個方法返回1個Int數值,  

例如 i = x.compareTo(y)

如果i=0, 也表明對象x與y排位上是相等的(並非意味x.equals(y) = true, 但是jdk api上強烈建議這樣處理)

如果返回數值i>0 則意味者, x > y啦, 

反之若i<0則 意味x < y

三, Comparable接口的實現及用法.

用回上面的例子, 我們修改Student類, 令其實現Comparable接口並重寫compareTo方法.

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

class Student implements Comparable{
    private String name;
    private int ranking;

    public Student(String name, int ranking){
        this.name = name;
        this.ranking = ranking;
    }

    public String toString(){
        return this.name + ":" + this.ranking;
    }

    public int compareTo(Object o){
        Student s = (Student)(o);
        return this.ranking - s.ranking;
    }
}

public class Compare2{
    public static void f(){
        ArrayList arr = new ArrayList();
        arr.add(new Student("Jack",10));
        arr.add(new Student("Bill",23));
        arr.add(new Student("Rudy",7));

        System.out.println(arr);
        Collections.sort(arr);
        System.out.println(arr);
    }
}

注意重寫的compareTo(Object o)方法內.  根據Student的ranking成員來比較的, 也就是說跟姓名無關了.

這時再編譯執行, 就能見到List容器內的Student對象已經根據ranking來排序了. 

輸出:

[java] [Jack:10, Bill:23, Rudy:7]
[java] [Rudy:7, Jack:10, Bill:23]

Copyright © Linux教程網 All Rights Reserved