GUAVA--基礎工具(Ordering)

一、排序器

排序器Ordering是Guava流暢風格比較器Comparator的實現,它能夠用來爲構建複雜的比較器,以完成集合排序的功能。java

從實現上說,Ordering 實例就是一個特殊的 Comparator 實例。Ordering把不少基於Comparator 的靜態方法(如 Collections.max)包裝爲本身的實例方法(非靜態方法),而且提供了鏈式調用方法,來定製和加強現有的比較器。算法

    比較器指的是集合存儲的元素的特性,若是元素是可比較的則能夠進行相應的排序,不然不行。可是在Java中有Comparable接口和Comparator接口,具體有什麼區別呢?app

對於Comparable接口來講,它每每是進行比較類須要實現的接口,它僅包含一個有compareTo()方法,只有一個參數,返回值爲int,返回值大於0表示對象大於參數對象;小於0表示對象小於參數對象;等於0表示二者相等。ide

Ordering類的聲明:google

@GwtCompatible
public abstract class Ordering<T> extends Object implements Comparator<T>

二、Ordering

2.一、建立Ordering實例

方法類型 方法名 描述
Ordering<Object> natural() 對可排序類型作天然排序,如數字按大小,日期按前後排序
按對象的字符串形式作字典排序[lexicographical ordering] usingToString() 返回由它們的字符串表示的天然順序,toString()比較對象進行排序。
Ordering<Object> arbitrary() 返回一個任意順序對全部對象,其中compare(a, b) == 0 意味着a == b(身份平等)。
Ordering<Object> allEqual() 返回一個排序,它把全部的值相等,說明「沒有順序。」經過這個順序以任何穩定的排序算法的結果,在改變沒有順序元素。
Ordering<T> explicit(List<T> valuesInOrder) 返回根據它們出現的定列表中的順序比較對象進行排序。
Ordering<T> explicit(T leastValue, T... remainingValuesInOrder) 返回根據它們所賦予本方法的順序進行比較的對象進行排序。
Ordering<U> compound(Comparator<? super U> secondaryComparator) 返回首先使用排序這一點,但它排序中的「tie」,而後委託給secondaryComparator事件。
Ordering<U> compound(Iterable<? extends Comparator<? super T>> comparators) 返回一個排序它嘗試每一個給定的比較器,以便直到一個非零結果找到,返回該結果,並返回零僅當全部比較器返回零。
Ordering<T> from(Comparator<T> comparator) 返回基於現有的比較實例進行排序。
Ordering<T> from(Ordering<T> ordering) 已取消使用

2.二、實例方法

方法比較多,大概有40多個,這裏只提出幾個比較經常使用的。code

方法類型 方法名 描述
Ordering<S> reverse() 獲取語義相反的排序器
Ordering<S> nullsFirst() 使用當前排序器,但額外把 null 值排到最前面。
Ordering<S> nullsLast() 使用當前排序器,但額外把 null 值排到最後面。
Ordering<U> compound(Comparator) 合成另外一個比較器,以處理當前排序器中的相等狀況。
Ordering<Iterable<S>> lexicographical() 基於處理類型 T 的排序器,返回該類型的可迭代對象 Iterable<T>的排序器。
Ordering<F> onResultOf(Function) 對集合中元素調用 Function,再按返回值用當前排序器排序。

實現自定義的排序器時,除了用上面的 from 方法,也能夠跳過實現 Comparator,而直接繼承 Ordering:對象

Ordering<String> byLengthOrdering = new Ordering<String>() {
	public int compare(String left, String right) {
		return Ints.compare(left.length(), right.length());
	}
};

2.三、舉例說明

2.3.一、簡單排序
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.google.common.collect.Ordering;

public class Guava {

	public static void main(String[] args) {

		List<Integer> numbers = new ArrayList<Integer>();
        numbers.add(new Integer(5));
        numbers.add(new Integer(2));
        numbers.add(new Integer(15));
        numbers.add(new Integer(51));
        numbers.add(new Integer(53));
        numbers.add(new Integer(35));
        numbers.add(new Integer(45));
        numbers.add(new Integer(32));
        numbers.add(new Integer(43));
        numbers.add(new Integer(16));
 
        Ordering ordering = Ordering.natural();
        System.out.println("Input List: ");
        System.out.println(numbers);
        /**
         * Input List: 
         * [5, 2, 15, 51, 53, 35, 45, 32, 43, 16]
         * */
        Collections.sort(numbers, ordering);
        System.out.println("Sorted List: ");
        System.out.println(numbers);
        /**
         *Sorted List: 
         * [2, 5, 15, 16, 32, 35, 43, 45, 51, 53]
         * */
        
        System.out.println("======================");
        System.out.println("List is sorted: " + ordering.isOrdered(numbers));
        // 根據此順序返回指定值中的最小值。若是有多個最小值,則返回第一個最小值。
        System.out.println("Minimum: " + ordering.min(numbers));
        // 根據這個順序返回指定值中的最大值。若是有多個最大值,則返回第一個值。
        System.out.println("Maximum: " + ordering.max(numbers));
        /**
         * List is sorted: true
         * 	Minimum: 2
         * 	Maximum: 53
         * */
        
        Collections.sort(numbers, ordering.reverse());
        System.out.println("Reverse: " + numbers);
        /**
         * Reverse: [53, 51, 45, 43, 35, 32, 16, 15, 5, 2]
         * */
        
        numbers.add(null);
        System.out.println("Null added to Sorted List: ");
        System.out.println(numbers);
        /**
         * Null added to Sorted List: 
         *[53, 51, 45, 43, 35, 32, 16, 15, 5, 2, null]
         * */
 
        Collections.sort(numbers, ordering.nullsFirst());
        System.out.println("Null first Sorted List: ");
        System.out.println(numbers);
        /**
         * Null first Sorted List: 
         *[null, 2, 5, 15, 16, 32, 35, 43, 45, 51, 53]
         * */
        System.out.println("======================");
 
        List<String> names = new ArrayList<String>();
        names.add("Ram");
        names.add("Shyam");
        names.add("Mohan");
        names.add("Sohan");
        names.add("Ramesh");
        names.add("Suresh");
        names.add("Naresh");
        names.add("Mahesh");
        names.add(null);
        names.add("Vikas");
        names.add("Deepak");
 
        System.out.println("Another List: ");
        System.out.println(names);
        /**
         * Another List: 
         *[Ram, Shyam, Mohan, Sohan, Ramesh, Suresh, Naresh, Mahesh, null, Vikas, Deepak]
         * */
 
        /**
         *  若是有null也加入排序計算 
         * Collections類中的sort方法能夠對實現了List接口的集合進行排序。這個方法假定列表元素實現了Comparable接口。
         * */
        Collections.sort(names, ordering.nullsFirst().reverse());
        System.out.println("Null first then reverse sorted list: ");
        System.out.println(names);
        /**
         * Null first then reverse sorted list: 
         *[Vikas, Suresh, Sohan, Shyam, Ramesh, Ram, Naresh, Mohan, Mahesh, Deepak, null]
         * */
	}
2.3.二、複合條件排序
import java.util.ArrayList;
import java.util.List;

import com.google.common.base.Function;
import com.google.common.base.MoreObjects;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;


public class Guava {

	public static void main(String[] args) {
		
		List<People> peopleList = new ArrayList<People>() {{
            add(new People("A", 33));
            add(new People("B", 11));
            add(new People("C", 18));
        }};
        
        List<People> po = Lists.newArrayList();
        po.addAll(peopleList);
        
        Ordering<People> ordering = Ordering.natural().onResultOf(new Function<People, Comparable>() {
            @Override
            public Comparable apply(People people) {
				// 此處能夠根據集合中的參數排序
                return people.getAge();
            }
        });
 
        for (People p : ordering.reverse().sortedCopy(po)) {
            System.out.println(MoreObjects.toStringHelper(p)
                    .add("name", p.getName())
                    .add("age", p.getAge())
            );
        }
        
	}
}
結果
People{name=A, age=33}
People{name=C, age=18}
People{name=B, age=11}
import java.util.ArrayList;
import java.util.List;

import com.google.common.base.Function;
import com.google.common.base.MoreObjects;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;


public class Guava {

	public static void main(String[] args) {
		
		List<People> peopleList = new ArrayList<People>() {{
            add(new People("A", 33));
            add(new People("B", 11));
            add(new People("C", 18));
        }};
        
        List<People> po = Lists.newArrayList();
        po.addAll(peopleList);
        
        Ordering<People> ordering = Ordering.usingToString().reverse().onResultOf(new Function<People, Comparable>() {
            @Override
            public Comparable apply(People people) {
                return people.getName();
            }
        });
 
        for (People p : ordering.sortedCopy(peopleList)) {
            System.out.println(MoreObjects.toStringHelper(p)
                    .add("name", p.getName())
                    .add("age", p.getAge())
            );
        }
        
	}
}
結果:
People{name=C, age=18}
People{name=B, age=11}
People{name=A, age=33}

3.小結

當閱讀鏈式調用產生的排序器時,應該從後往前讀。上面的例子中,排序器首先調用 apply 方法獲取 people 值,並把剩下的元素按 people 進行排序。之因此要從後往前讀,是由於每次鏈式調用都是用後面的方法包裝了前面的排序器。排序

注:用 compound 方法包裝排序器時,就不該遵循從後往前讀的原則。爲了不理解上的混亂,請不要把 com pound 寫在一長串鏈式調用的中間,你能夠另起一行,在鏈中最早或最後調用 compound。超過必定長度的鏈式調用,也可能會帶來閱讀和理解上的難度。咱們建議按下面的代碼這樣,在一個鏈中最多使用三個方法。此外,你也能夠把 Function 分離成中間對象,讓鏈式調用更簡潔緊湊。繼承

Ordering<Foo> ordering = Ordering.natural().nullsFirst().onResultOf(sortKeyFunction)接口

相關文章
相關標籤/搜索