我們經常會遇到排序的需求,String類型和Integer類型JDK提供了排序方法:
public class ComparableTest {
public static void main(String[] args) {
Integer data [] = new Integer[] {6,5,2,8,5,1,6,4,6};
Arrays.sort(data);
System.out.println(Arrays.toString(data));
}
}
[1, 2, 4, 5, 5, 6, 6, 6, 8]
但是如果我們要對某個自定義的類的對象進行排序,就需要定義比較規則才能進行比較和排序,而制定比較規則就需要比較器,主要的比較器分爲Comparable和Comparator比較器。
Comparable比較器
class Item implements Comparable<Item>{
private String name;
private int num;
public Item(String name, int num) {
this.name = name;
this.num = num;
}
public String getName() {
return name;
}
public int getNum() {
return num;
}
@Override
public int compareTo(Item item) {
// 從小到大 :this‐o
// 從大到小:o‐this
return item.num - this.num;
}
}
public class ComparableTest {
public static void main(String[] args) {
List<Item> list = new ArrayList<Item>();
list.add(new Item("a", 21));
list.add(new Item("b", 8));
list.add(new Item("c", 1));
list.add(new Item("d", 9));
Collections.sort(list);
list.forEach(it -> {
System.out.println(it.getName() + " -> " + it.getNum());
});
}
}
a -> 21
d -> 9
b -> 8
c -> 1
其中,compareTo()方法進行排序規則的定義。
// 從小到大 :this‐o
// 從大到小:o‐this
//比較方法升級:先根據數量排序,如果數量一樣,根據名稱排序
if (this.num!=o.num) {
return this.num - o.num;
} else {
return this.name.compareTo(o.name);
}
}
}
Comparator比較器
這個挽救型比較器,因爲Comparable比較器是需要被比較的對象的類實現Comparable接口的,若在設計之初未考慮比較功能,後面發現需要比較功能,而又不能隨意修改代碼,就可以用Comparator比較器。
使用Comparator時不要求被比較的類實現Comparable接口,但是需要一個額外的比較器類。
class Items {
private String name;
private int num;
public Items(String name, int num) {
this.name = name;
this.num = num;
}
public String getName() {
return name;
}
public int getNum() {
return num;
}
}
class ItemsComparator implements Comparator<Items> {
@Override
public int compare(Items o, Items o1) {
return o.getNum() - o1.getNum();
}
}
public class ComparatorTest {
public static void main(String[] args) {
List<Items> list = new ArrayList<Items>();
list.add(new Items("a", 21));
list.add(new Items("b", 8));
list.add(new Items("c", 1));
list.add(new Items("d", 9));
Collections.sort(list, new ItemsComparator());
list.forEach(it -> {
System.out.println(it.getName() + " -> " + it.getNum());
});
}
}
c -> 1
b -> 8
d -> 9
a -> 21
Comparable和Comparator的區別
- Comparable是在類定義時實現的父接口,comparaTo()用於定義比較規則
- Comparator是挽救比較器,需要設置單獨的比較器規則類,並實現Comparator接口,通過compare()方法實現比較規則的定義
實際開發中,若有比較需求,最好選用Comparable比較器。