iT邦幫忙

2024 iThome 鐵人賽

0
自我挑戰組

前端工程師的java學習紀錄系列 第 38

Day38-Comparable、Comparator

  • 分享至 

  • xImage
  •  

Comparable 是一個比較大小的接口,在比較基本數據類型時可以直接使用> < 的方式進行比較,但是引用數據類型所存放的是記憶中的地址,所以不能直接使用> < 比較大小。

以下用Arrayssort 方法進行示範

String[] arr = new String[]{"banana", "apple", "orange", "lemon"};
Arrays.sort(arr); // ["apple", "banana", "lemon", "orange"]

印出的值

["apple", "banana", "lemon", "orange"]

假設有這樣的一個類

class Product {
	String name;
	int price;
	
	public Product(name, price) {
		this.name = name;
		this.price = price;
	}
    
    public int getPrice() {
		return price;
	}
	
	@Override
	public String toString() {
		return "Product{" + "name=" + name + '\'' + ", price=" + price + '}';
	}
}

進行排序會報錯ClassCastException 。Product不能轉換成Comparable

Product[] arr = new Product[4];
arr[0] = new Product("banana", 50);
arr[1] = new Product("apple", 20);
arr[2] = new Product("lemon", 70);
arr[3] = new Product("orange", 30);

Arrays.sort(arr); // ClassCastException

原因在於Product並沒有實作Comparable這個接口的抽象方法compareTo 。(String本身是有去實作的)

改寫Product類實作Comparable

class Product implements Comparable {
	//...略
	@Override
	public int compareTo(Object o) {
		if(o == this) {
			return 0;
		}
		
		if(o instanceof Product) {
			Product p = (Product) o; // 進行強制轉換類型
			
			if(this.price == p.price) {
				return 0;
			}
			
			if(this.price > p.price) {
				return 1;
			}
			
			if(this.price < p.price) {
				return -1;
			}
		}
		
		throw new RuntimeException("類型錯誤");
	}
}

再進行一次排序

Product[] arr = new Product[4];
arr[0] = new Product("banana", 50);
arr[1] = new Product("apple", 20);
arr[2] = new Product("lemon", 70);
arr[3] = new Product("orange", 30);

Arrays.sort(arr);

for(int i = 0; i < arr.length; i++) {
	System.out.println(arr[i]);
}

印出的值

Product{name='apple', price=20}
Product{name='orange', price=30}
Product{name='banana', price=50}
Product{name='lemon', price=70}

Comparator 是一個比較大小的接口,與Comparable 不同的地方在於,它主要用於當某個類已經有使用Comparable 進行比較的實作,但是無法對它的程式碼進行修改,這時候就需要使用Comparator 。(例如String 中已經有實作Comparable

使用方式:需要創建一個實作Comparator 接口的實例,並且將抽象方法compare 實作

Product[] arr = new Product[4];
arr[0] = new Product("banana", 50);
arr[1] = new Product("apple", 20);
arr[2] = new Product("lemon", 70);
arr[3] = new Product("orange", 30);

Comparator comparator = new Comparator(){
	@Override
	public int compare(Object obj1, Object obj2) {
		if(obj1 instanceof Product && obj2 instanceof Product) {
			Product p1 = (Product) obj1;
			Product p2 = (Product) obj2;
			
			if(p1.getPrice() > p2.getPrice()) {
				return 1;
			}
			
			if(p1.getPrice() < p2.getPrice()) {
				return -1;
			}
			
			if(p1.getPrice() == p2.getPrice()) {
				return 2;
			}
			
			throw new RuntimeException("類型錯誤");
		}
	}
}

Array.sort(arr, comparator); // sort方法如果傳入第二個參數,會使用該參數的方法去比較

Comparable

  1. 單一。
  2. 實作的抽象方法是compareTo(Object obj) 。(因為是使用類本身的方法,所以只需要將要比較的物件傳入參數中)

Comparator

  1. 靈活。
  2. 實作的抽象方法是compare(Object obj1, Object obj2) 。(因為使用的是實作Comparator 接口的物件,並非要比較物件,所以必須將兩個要進行比較的物件傳入參數中)

上一篇
Day37-Time
下一篇
Day39-集合Collection
系列文
前端工程師的java學習紀錄41
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言