淺談Comparable與Comparator的區別
平時進行自定義排序一直使用實現 Comparable 介面,一段時間後操作的時候居然發現有了個 Comparator 介面
上網差了些資料,總結筆記一下。
基本原理就是比較,底層是 二叉樹
比如是3,6,5,1,7,4,9
排序的時候先放入3,之後6比3大,煩惱如3右邊,5比6小,放左邊,一次類推就是線面這圖
首先看一下Comparable的介面定義
package java.lang; import java.util.*; public interface Comparable<T> { public int compareTo(T o); }
Comparable對實現它的每個類的物件進行整體排序。這個介面需要類本身去實現
程式碼例項分析
package com.list.customsort; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class TestSort { public static void main(String[] args) { List<Person> list = new ArrayList<>(); list.add(new Person("fd",20)); list.add(new Person("chy",22)); list.add(new Person("wgj",21)); System.out.println(list); Collections.sort(list); System.out.println(list); } } class Person implements Comparable<Person>{ private String name; private Integer age; public Person(String name, Integer age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } @Override public int compareTo(Person o) { //return this.getAge().compareTo(o.getAge()); return this.getName().compareTo(o.getName());//按姓名進行正序排序。abc } }
是根據person的name屬性進行排序 結果:
不使用Collections.sort()方法的話,可以直接使用treeSet集合進行操作
Set<Person> set = new TreeSet<>(); set.add(new Person("fd",20)); set.add(new Person("chy",22)); set.add(new Person("wgj",21)); System.out.println(set);
結果跟上面時一模一樣的也是根據name來實現了排序
為什麼呢,檢視treeset原始碼會發現走還是compareto方法
所以使用Collections.sort(list) 跟直接new TreeSet是一樣的效果。
Comparator
Comparator是比較介面,我們如果需要控制某個類的次序,而該類本身不支援排序(即沒有實現Comparable介面),那麼我們就可以建立一個“該類的比較器”來進行排序,這個“比較器”只需要實現Comparator介面即可。也就是說,我們可以通過實現Comparator來新建一個比較器,然後通過這個比較器對類進行排序。
介面定義
package java.util; public interface Comparator<T> { int compare(T o1, T o2); boolean equals(Object obj); }
程式碼例項分析
package com.list.customsort; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Set; import java.util.TreeSet; public class TestSort2 { public static void main(String[] args) { List<Person2> list = new ArrayList<>(); list.add(new Person2("fd",20)); list.add(new Person2("chy",22)); list.add(new Person2("wgj",21)); System.out.println(list); Collections.sort(list,new Comparator<Person2>() { @Override public int compare(Person2 o1, Person2 o2) { return o1.getAge().compareTo(o2.getAge()); } }); System.out.println(list); } } class Person2{ private String name; private Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Person2(String name, Integer age) { super(); this.name = name; this.age = age; } @Override public String toString() { return "Person2 [name=" + name + ", age=" + age + "]"; } }
main方法的sort方法可以使用lambda來進行簡化
(public static <T> void sort(List<T> list, Comparator<? super T> c) )
Collections.sort(list,(s1,s2)-> Integer.compare(s1.getAge(),s2.getAge()));
這個時候使用treeset集合的話就沒效果了。
因為它底層使用的是compareTo方法。
Comparable和Comparator區別比較
Comparable是排序介面,若一個類實現了Comparable介面,就意味著“該類支援排序”。而Comparator是比較器,我們若需要控制某個類的次序,可以建立一個“該類的比較器”來進行排序。
Comparable相當於“內部比較器”,而Comparator相當於“外部比較器”。
兩種方法各有優劣, 用Comparable 簡單, 只要實現Comparable 介面的物件直接就成為一個可以比較的物件,但是需要修改原始碼。 用Comparator 的好處是不需要修改原始碼, 而是另外實現一個比較器, 當某個自定義的物件需要作比較的時候,把比較器和物件一起傳遞過去就可以比大小了, 並且在Comparator 裡面使用者可以自己實現複雜的可以通用的邏輯,使其可以匹配一些比較簡單的物件,那樣就可以節省很多重複勞動了。