一、Comparable 和 Comparator 架構圖
java.util.Collection (介面)
│
├── java.util.List (介面) -- 有序,可重複
│ ├── java.util.ArrayList (類別) -- 動態陣列
│ ├── java.util.LinkedList (類別) -- 雙向鏈結串列
│ └── java.util.Vector (類別) -- 執行緒安全的動態陣列
│
├── java.util.Set (介面) -- 無序,不重複
│ ├── java.util.HashSet (類別) -- 基於 HashMap
│ ├── java.util.LinkedHashSet (類別) -- 保留插入順序
│ └── java.util.TreeSet (類別) -- 基於紅黑樹,自然排序
│
└── java.util.Queue (介面) -- 先進先出(FIFO)
├── java.util.PriorityQueue (類別) -- 依優先級排序
└── java.util.Deque (介面) -- 雙端隊列
├── java.util.ArrayDeque (類別)
└── java.util.LinkedList (類別) -- 也同時實作了 List
二、Comparable 和 Comparator 的差異
特性:
2個介面Comparable、Comparator,用來排序物件
Module.java.base
Package.java.langInterface Comparable<T>
Module.java.base
Package.java.util Interface Comparator<T>
在 Java 中,Comparable
和 Comparator
介面都是用於對物件進行排序。
它們的主要差異如下:
三、Comparable與
Comparator` 的差異比較表
補充:什麼是自然排序?
答案:數字排在大寫字母之前,大寫字母排在小寫字母之前。
四、實作一個Comparable範例
Comparable<Laptop>
介面Laptop.java
package Geeks;
import java.util.Comparator;
public class Laptop implements Comparable<Laptop>{
private String brand;
private int ram;
private int price;
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public int getRam() {
return ram;
}
public void setRam(int ram) {
this.ram = ram;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public String toString() {
return "Laptop [brand=" + brand + ", ram=" + ram + ", price=" + price + "]";
}
//加上建構子,才可以在ComparableRunner.java使用new Laptop("Apple",8,1200)等
public Laptop(String brand, int ram, int price) {
super();
this.brand = brand;
this.ram = ram;
this.price = price;
}
@Override
public int compareTo(Laptop lap2) {
//需要一個參數來做排序
//this是"本物件"
//this > lap2 = 正數
//this < lap2 = 負數
//this == lap2 0
//使用ram這個欄位自然排序
if(this.getRam() > lap2.getRam()) {
return 1; //回傳正數
}else {
return -1;
}
}
}
ComparableRunner.java
package Geeks;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ComparableRunner {
public static void main(String[] args) {
List<Laptop> laps = new ArrayList<>();
laps.add(new Laptop("Acer", 12, 700));
laps.add(new Laptop("Asus", 8, 600));
laps.add(new Laptop("Dell", 6, 900));
laps.add(new Laptop("Apple", 8, 1200));
//不知道要用哪一個排序brand or ram or price
//Collection是泛型介面,是集合家族的共同祖先。Collection有2個很重要的子介面: Set、List
//Collections 工具類別 - 用於List物件
//將List傳送進Collections.sort的方法
Collections.sort(laps);
for(Laptop l: laps) {
System.out.println(l);
}
}
}
五、實作一個Comparator範例
package Geeks;
import java.util.Comparator;
// 不需要實作 Comparator 介面
public class Laptop{
private String brand;
private int ram;
private int price;
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public int getRam() {
return ram;
}
public void setRam(int ram) {
this.ram = ram;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public String toString() {
return "Laptop [brand=" + brand + ", ram=" + ram + ", price=" + price + "]";
}
//加上建構子
public Laptop(String brand, int ram, int price) {
super();
this.brand = brand;
this.ram = ram;
this.price = price;
}
}
ComparatorRunner.java
package Geeks;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ComparatorRunner {
public static void main(String[] args) {
List<Laptop> laps = new ArrayList<>();
laps.add(new Laptop("MSI", 10, 1000));
laps.add(new Laptop("Sony", 8, 600));
laps.add(new Laptop("Lenovo", 6, 900));
laps.add(new Laptop("Asus", 8, 1200));
Comparator<Laptop> com = new Comparator<>() {
//依品牌字母順序
public int compare(Laptop l1, Laptop l2) {
return l1.getBrand().compareTo(l2.getBrand());
}
};
Collections.sort(laps, com);
for (Laptop l : laps) {
System.out.println(l);
}
}
}
參考資料
Interview Question | Comparable vs Comparator in Java
https://www.youtube.com/watch?v=oAp4GYprVHM
Java Comparable vs Comparator
https://www.geeksforgeeks.org/java/comparable-vs-comparator-in-java/