【java】Comparator的用法

轉載請標明出處:http://blog.csdn.net/u012250875/article/details/55126531

1.爲什麼寫?

  1. comparator 是javase中的接口,位於java.util包下,該接口抽象度極高,有必要掌握該接口的使用
  2. 大多數文章告訴大家comparator是用來排序,但我想說排序是comparator能實現的功能之一,他不僅限於排序

2.接口功能

該接口代表一個比較器,比較器具有可比性!大多數文章都寫如何用comparator排序,是因爲javase數組工具類和集合工具類中提供的sort方法sort就是使用Comparator接口來處理排序的,大家見久了都認爲Comparator接口是用來排序的,按照java抽象的尿性來看,該接口如果爲排序而生,應該叫Sortable,Sortor之類的名字吧!下面是javase一些使用到Comparator接口的地方:

Arrays.sort(T[],Comparator<? super T> c);
Collections.sort(List<T> list,Comparator<? super T> c);

3.使用場景

什麼場景需要做比較,那麼什麼場景就是Comparator接口的用武之地,我總結的兩個場景:
1. 排序,需要比較兩個對象誰排在前誰排在後(排序也可以讓類實現Comparable接口,實現後該類的實例也具有排序能力)。
2. 分組,需要比較兩個對象是否是屬於同一組。
3. 待補充

4.舉個栗子

1.排序
在List或數組中的對象如果沒有實現Comparable接口時,那麼就需要調用者爲需要排序的數組或List設置一個Compartor,Compartor的compare方法用來告訴代碼應該怎麼去比較兩個實例,然後根據比較結果進行排序

talk is cheap show me the code

package com.java.demo;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
 * @author puyf
 */
public class SortTest {
    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 SortTest().new Dog(5, "DogA"));
    list.add(new SortTest().new Dog(6, "DogB"));
    list.add(new SortTest().new Dog(7, "DogC"));
    Collections.sort(list, new Comparator<Dog>() {

        @Override
        public int compare(Dog o1, Dog o2) {
        return o2.age - o1.age;
        }
    });
    System.out.println("給狗狗按照年齡倒序:"+list);
    Collections.sort(list, new Comparator<Dog>() {

        @Override
        public int compare(Dog o1, Dog o2) {
        return o1.name.compareTo(o2.name);
        }
    });
    System.out.println("給狗狗按名字字母順序排序:"+list);
    }
}

2.分組
使用Comparator和for循環處理列表,來進行分類;通過調用者實現Comparator接口的比較邏輯,來告訴程序應該怎麼比較,通過比較之後得結果來進行分組。比如生活中的拳擊比賽,會有公斤級的概念,那麼程序中應該實現的處理邏輯是隻要兩個人的體重在同一個區間則爲同一組公斤級的選手。下面例子中分別按照狗狗的顏色和體重級別兩個維度來進行分組,因此分組的核心邏輯其實就是比較邏輯。相面我抽了一個工具方法:dividerList,第一個參數爲需要處理的數據源,第二參數是分組時的比較邏輯。

package com.java.demo;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
/**
 * @author puyf
 */
public class GroupTest {
    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 + "]";
    }
    }

    /**
     * @author puyf
     * @Description:按條件分組
     * @param datas
     * @param c
     *            是否爲同一組的判斷標準
     * @return
     */
    public static <T> List<List<T>> divider(Collection<T> datas, Comparator<? super 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;
    }

    public static void main(String[] args) {
    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 = divider(list, new Comparator<Apple>() {

        @Override
        public int compare(Apple o1, Apple o2) {
        // 按顏色分組
        return o1.color.compareTo(o2.color);
        }
    });
    System.out.println("按顏色分組" + byColors);
    List<List<Apple>> byWeight = divider(list, new Comparator<Apple>() {

        @Override
        public int compare(Apple o1, Apple o2) {
        // 按重量級

        return (o1.weight / 100 == o2.weight / 100) ? 0 : 1;
        }
    });
    System.out.println("按重量級分組" + byWeight);
    }
}

結果如下(爲了方便看,手動回車換行格式化了下):
按顏色分組
[
[
Apple [color=紅, weight=205],
Apple [color=紅, weight=131]
],
[
Apple [color=綠, weight=248],
Apple [color=綠, weight=153]
],
[
Apple [color=黃, weight=119],
Apple [color=黃, weight=224]
]
]

按重量級分組
[
[
Apple [color=紅, weight=205],
Apple [color=綠, weight=248],
Apple [color=黃, weight=224]
],
[
Apple [color=紅, weight=131],
Apple [color=綠, weight=153],
Apple [color=黃, weight=119]
]
]

5.總結

一般需要做比較的邏輯都可以使用的上Comparator,最常用的場景就是排序和分組,排序常使用Arrays和Collections的sort方法,而分組則可以使用上面提供的divider方法。

排序和分組的區別在於:
排序時,兩個對象比較的結果有三種:大於,等於,小於。
分組時,兩個對象比較的結果只有兩種:等於(兩個對象屬於同一組),不等於(兩個對象屬於不同組)

發佈了28 篇原創文章 · 獲贊 63 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章