comparator 是javase中的接口,位於java.util包下,該接口抽象度極高,有必要掌握該接口的使用,排序是comparator能實現的功能之一,他不僅限於排序,還有分組
接口功能:
該接口代表一個比較器,比較器具有可比性!大多數文章都寫如何用comparator排序,是因為javase數組工具類和集合工具類中提供的sort方法sort就是使用Comparator接口來處理排序的
Arrays.sort(T[],Comparator<? super T> c); Collections.sort(List<T> list,Comparator<? super T> c);
使用場景:
1.排序,需要比較兩個對象誰排在前誰排在后(排序也可以讓類實現Comparable接口,實現后該類的實例也具有排序能力)。
2.分組,需要比較兩個對象是否是屬於同一組。
舉例說明:
排序
通過實現Comparator接口,定義需要排序的字段
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; /** * 實現Comparator 的排序功能 * @author gcc * * 2018年3月6日 */ public class TestComparator { class Dog{ public int age; public String name; public Dog(int age,String name) { super(); this.age = age; this.name = name; } @Override public String toString() { return "Dog [age=" + age + ", name=" + name + "]"; } } public static void main(String[] args) { List<Dog> list= new ArrayList<>(); list.add(new TestComparator().new Dog(8, "DogA")); list.add(new TestComparator().new Dog(6, "DogB")); list.add(new TestComparator().new Dog(7, "DogC")); //按年齡排序 Collections.sort(list,new TestComparator().new SortDogAge()); System.out.println("給狗狗按照年齡倒序:"+list); //按姓名排序 Collections.sort(list,new TestComparator().new SortDogName()); System.out.println("給狗狗按名字字母順序排序:"+list); } /** * 按照年齡排序 * @author gcc * * 2018年3月6日 */ class SortDogAge implements Comparator<Dog>{ @Override public int compare(Dog o1, Dog o2) { return o1.age-o2.age; } } /** * 按照名字排序 * @author gcc * * 2018年3月6日 */ class SortDogName implements Comparator<Dog>{ @Override public int compare(Dog o1, Dog o2) { return o1.name.compareTo(o2.name); } } }
分組
使用Comparator和for循環處理列表,來進行分類;通過調用者實現Comparator接口的比較邏輯,來告訴程序應該怎么比較,通過比較之后得結果來進行分組。比如生活中的拳擊比賽,會有公斤級的概念,那么程序中應該實現的處理邏輯是只要兩個人的體重在同一個區間則為同一組公斤級的選手。下面例子中分別按照狗狗的顏色和體重級別兩個維度來進行分組,因此分組的核心邏輯其實就是比較邏輯。相面我抽了一個工具方法:dividerList,第一個參數為需要處理的數據源,第二參數是分組時的比較邏輯。
import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.List; import com.gcc.interview.TestComparator.Dog; /** * 分組 * @author gcc * * 2018年3月6日 */ public class GroupTest implements Divider{ class Apple { public String color; public int weight; public Apple(String color, int weight) { super(); this.color = color; this.weight = weight; } @Override public String toString() { return "Apple [color=" + color + ", weight=" + weight + "]"; } } public <T> List<List<T>> divider(Collection<T> datas,Comparator<T> c) { List<List<T>> result = new ArrayList<List<T>>(); for(T t:datas) { boolean isSameGroup = false; for(int j=0;j<result.size();j++) { if(c.compare(t, result.get(j).get(0))==0) { isSameGroup = true; result.get(j).add(t); break; } } if (!isSameGroup) { // 創建 List<T> innerList = new ArrayList<T>(); result.add(innerList); innerList.add(t); } } return result; } /** * 按照顏色分組 * @author gcc * * 2018年3月6日 */ class SortAppleColor implements Comparator<Apple>{ @Override public int compare(Apple o1, Apple o2) { // TODO Auto-generated method stub return o1.color.compareTo(o2.color); } } /** * 按照重量分組 * @author gcc * * 2018年3月6日 */ class SortAppleWeight implements Comparator<Apple>{ @Override public int compare(Apple o1, Apple o2) { return o1.weight-o2.weight; } } public static void main(String[] args) { GroupTest test = new GroupTest(); List<Apple> list = new ArrayList<>(); list.add(new GroupTest().new Apple("紅", 205)); list.add(new GroupTest().new Apple("紅", 131)); list.add(new GroupTest().new Apple("綠", 248)); list.add(new GroupTest().new Apple("綠", 153)); list.add(new GroupTest().new Apple("黃", 119)); list.add(new GroupTest().new Apple("黃", 224)); List<List<Apple>> byColors = test.divider(list,new GroupTest().new SortAppleColor()); System.out.println("按顏色分組" + byColors); List<List<Apple>> byWeights = test.divider(list,new GroupTest().new SortAppleColor()); System.out.println("按重量分組" + byWeights); } }