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)接口

相关文章
相关标签/搜索