Java Comparable 與 Comparator

chi633發表於2017-12-21

在收集物件之後,物件的排序是經常需要用到的操作。但我們不需要親自實現各種排序演算法,java.util.Collections提供了sort方法,List作為一種collections,而且存在索引,所以可以呼叫sort方法進行排序。顯然,必須具有索引,才能進行排序。

package Collection;

import java.util.*;

public class Sort {

	public static void main(String[] args) {
		List numbers = Arrays.asList(1,2,3,4,5,6,8,7,12,1);
		Collections.sort(numbers);
		System.out.println(numbers);
	}

}

複製程式碼

執行結果是將資料進行由小到大的排序:

Paste_Image.png

但如果是下面這個例子呢?

package Collection;

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

public class Sort2 {
	
	

	public static void main(String[] args) {
		List accounts = Arrays.asList(
                new Account("Justin", "X1234", 1000),
                new Account("Monica", "X5678", 500),
                new Account("Irene", "X2468", 200)
        );
        Collections.sort(accounts);
        System.out.println(accounts);

	}

}

class Account {
	private String name;
	private String numbers;
	private double balance;
	
	Account(String name,String numbers,double balance) {
		this.name = name;
		this.numbers = numbers;
		this.balance = balance;
	}
	
	@Override
	public String toString() {
		return String.format("Account(%s,%s,%d)", name,numbers,balance);
	}
}

複製程式碼

執行之後,我們發現程式報錯了:

Paste_Image.png

錯誤資訊是,我們定義的Account無法轉換為Comparable型別。 顯然,這就是說明collection的sort方法必須室友comparable類的物件進行呼叫,因為我們既然要對物件進行排序,顯然就要告訴程式如何對物件進行排序,是按什麼排?這就需要去實現comparable介面,這是一個形容詞,也就是表明,物件是可比較大小的,那自然就可以排序了。這個介面有一個comparaTo的方法,必須返回大於0,小於0或者等於0的數,這就是sort的排序方式。

所以接下來我們就改寫上面的例子,使其更具賬戶餘額的大小進行排序。

package Collection;

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

public class Sort3 {
	
	

	public static void main(String[] args) {
		List accounts = Arrays.asList(
                new Account2("Justin", "X1234", 1000),
                new Account2("Monica", "X5678", 500),
                new Account2("Irene", "X2468", 200)
        );
        Collections.sort(accounts);
        System.out.println(accounts);

	}

}

class Account2 implements Comparable<Account2> {
	private String name;
	private String numbers;
	private double balance;
	
	Account2(String name,String numbers,double balance) {
		this.name = name;
		this.numbers = numbers;
		this.balance = balance;
	}
	
	@Override
	public String toString() {
		return String.format("Account(%s,%s,%f)", name,numbers,balance);
	}

	

	@Override
	public int compareTo(Account2 o) {
		// TODO Auto-generated method stub
		
		return (int) (this.balance - o.balance);
	}
	
	
}

複製程式碼

Paste_Image.png

這就根據銀行餘額的值返回了正確的結果,所以我們知道,要對物件進行排序,首先一定要是可比較大小的,不然怎麼排序,要可比較大小,就需要繼承實現comparable介面,實現裡面的comparaTo方法,定義排序的規則。

那麼疑問來了,為什麼我們的第一個例子,可以正確的對integer進行排序呢? 那是因為jdk已經預設幫integer實現了comparable介面。 但問題還是來了,如果我們希望integer的排序方法由大到小呢?那怎麼辦,難道我們需要重新去實現integer的comparable介面的comparaTo方法?顯然這是不現實的,因為這些都是在jdk預設提供的api裡,這時候,我們發現,還有一個comparator介面。

Collections的sort()方法有另一個過載的版本,可接受java.util.Comparator介面的的例項物件,如果你使用這個版本,排序方式就將根據Comparator的compare()定義來決定。

package Collection;

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

public class Sort5 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		List<String> words = Arrays.asList("B", "X", "A", "M", "F", "W", "O");
		Collections.sort(words, new Comparator<String>() {

			@Override
			public int compare(String o1, String o2) {
				// TODO Auto-generated method stub
				return -o1.compareTo(o2);
			}
			
		});
		
		System.out.println(words);
	}

}
複製程式碼

Paste_Image.png

在Java中,根據順序有關的行為要麼是實現了comparable介面,要麼就是實現了comparator介面型別。

相關文章