Java排序器之升序or降序


一、如何確定升序還是降序?

Java中在進行對象排序時,設計的排序器經常會對兩個對象按照一定的排序規則排序,可如何確定排序規則是升序還是降序呢?筆者整理了一個簡單的方法來確定排序規則。

o1和o2是需要表示排序的兩個對象,假定比較前的默認順序為 [o1, o2],是升序還是降序暫時不做考慮,完全根據返回值結果表示是否需要調整當前的排序順序,便能夠理解排序的真正邏輯,以確定是升序排序還是降序排序。

假設我們的比較器規則如下:o1對象作為比較的前者,o2對象作為排序的后者,即比較方式為 [o1 - o2]或者 [o1.compareTo(o2)]。

class ComparatorByAge implements Comparator {

    // 根據年齡和姓名排序
 @Override public int compare(Object o1, Object o2) { Person p1 = (Person) o1; Person p2 = (Person) o2; int tmp = p1.getAge() - p2.getAge(); return tmp == 0 ? p1.getName().compareTo(p2.getName()) : tmp; } }

升序規則:

  • o1 > o2,返回正數,true,表示需要調整順序,升序。
  • o1 < o2,返回負數,false,表示不需要調整順序,升序。
降序規則:
  • o1 > o2,返回負數,false,表示不需要調整順序,降序。
  • o1 < o2,返回正數,true,表示需要調整順序,降序。 
不排序規則:
  • o1 = o2,返回0,按當前順序即可,或者比較其他參數。

二、實際用例

Person 是定義的需要排序的對象,包括年齡和姓名兩個字段。
class Person implements Comparable{

    private String name;
    private int age;

    // 重寫toString()方法,輸出對象時輸出格式為:name:age
    @Override
    public String toString() {
        return name+ ":" + age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    // Person自帶的排序規則
    @Override
    public int compareTo(Object o) {
        Person p = (Person) o;

    // 根據年齡進行排序
      int temp = this.age - p.age;
      return temp == 0 ? this.name.compareTo(p.name):temp;
    }
}
View Code

排序規則一:定義升序排序器,先按年齡升序,再按姓名首字母升序。

  • 比如 o1對象為 (zhangshan:20) ,o2 對象為 (wangwu:21) ,默認排序 [o1, o2],由於 o1.age < o2.age,比較結果返回負數,false,表示不需要調整規則,按年齡升序排序,最終排序結果為 [zhangshan:20, wangwu:21]。
  • 比如 o1 對象為 (zhangshan:20) ,o2對象為 (lisi:20),默認排序 [o1,o2],由於 o1.age = o2.age,比較結果為0,不按年齡排序,進一步比較name,由於 o1.name > o2.name,返回 true,調整排序規則,即按字母升序排序,最終排序結果為 [lisi:20, zhangshan:20]。
/**
 * 自定義升序排序器
 * 升序:先按年齡升序,再按姓名首字母升序
 */
class ComparatorByAge implements Comparator {

    // 根據年齡排序
 @Override public int compare(Object o1, Object o2) { Person p1 = (Person) o1; Person p2 = (Person) o2; int tmp = p1.getAge() - p2.getAge(); return tmp == 0 ? p1.getName().compareTo(p2.getName()) : tmp; } }

排序規則二:定義降序排序器,先按年齡降序,再按姓名首字母降序。和升序的唯一區別就是返回結果的參數前添加了一個負號。

/**
 * 自定義降序排序器
 * 降序:先按年齡降序,再按姓名首字母降序
 */
class ComparatorByAge2 implements Comparator {

    // 根據年齡排序
 @Override public int compare(Object o1, Object o2) { Person p1 = (Person) o1; Person p2 = (Person) o2; int tmp = p1.getAge() - p2.getAge(); return tmp == 0 ? -(p1.getName().compareTo(p2.getName())) : -tmp; } }

排序 main() 方法,查看兩種排序器的排序結果。

public class TreeSetDemo {
    public static void main(String[] args) {
        TreeSet<Person> ts = new TreeSet(new ComparatorByAge());
        ts.add(new Person("zhangsan", 20));
        ts.add(new Person("wangwu", 21));
        ts.add(new Person("lisi", 20));
        ts.add(new Person("zhouqi", 29));
        ts.add(new Person("zhaoliu", 28));

        for (Person person : ts) {
            System.out.println(person);
        }
        /* 結果輸出
        lisi:20
        zhangsan:20
        wangwu:21
        zhaoliu:28
        zhouqi:29
        */

        ts = new TreeSet(new ComparatorByAge2());
        ts.add(new Person("zhangsan", 20));
        ts.add(new Person("wangwu", 21));
        ts.add(new Person("lisi", 20));
        ts.add(new Person("zhouqi", 29));
        ts.add(new Person("zhaoliu", 28));
        for (Person person : ts) {
            System.out.println(person);
        }
        /* 結果輸出
        zhouqi:29
        zhaoliu:28
        wangwu:21
        zhangsan:20
        lisi:20
        */
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM