首页 > 代码库 > Guava源码学习(二)Ordering

Guava源码学习(二)Ordering

基于版本:Guava 22.0

Wiki:Ordering

 

0. Ordering简介

Guava的Ordering提供了链式风格的比较器的实现,我们可以用Ordering轻松构建复杂的比较器。

 

1. 类图

技术分享

这张类图不完全,实际上Ordering有十几个子类,这些子类共同提供了复杂的功能。

 

2. 设计思路

Ordering是继承于java.util.Comparator接口的抽象类,它的十几个子类都实现了compare与equals方法,这些子类可以实现基本的排序功能。

通过链式调用,可以将这些子类组合在一起,实现复杂的排序规则。

举个例子:

Ordering combineOrdering = Ordering.natural().reverse().nullsFirst();

对应的源码如下

Ordering.nullsFirst()
  @GwtCompatible(serializable = true)
  public <S extends T> Ordering<S> nullsFirst() {
    return new NullsFirstOrdering<S>(this);
  }

Ordering.reverse()
  @GwtCompatible(serializable = true)
  public <S extends T> Ordering<S> reverse() {
    return new ReverseOrdering<S>(this);
  }


NullsFirstOrdering.class
  final Ordering<? super T> ordering;

  NullsFirstOrdering(Ordering<? super T> ordering) {
    this.ordering = ordering;
  }

  @Override
  public int compare(@Nullable T left, @Nullable T right) {
    if (left == right) {
      return 0;
    }
    if (left == null) {
      return RIGHT_IS_GREATER;
    }
    if (right == null) {
      return LEFT_IS_GREATER;
    }
    return ordering.compare(left, right);
  }


ReverseOrdering.class
  final Ordering<? super T> forwardOrder;

  ReverseOrdering(Ordering<? super T> forwardOrder) {
    this.forwardOrder = checkNotNull(forwardOrder);
  }

  @Override
  public int compare(T a, T b) {
    return forwardOrder.compare(b, a);
  }

可以看出combineOrdering实际上是由外部的NullsFirstOrdering加上内部ReverseOrdering嵌套而成的

在调用combineOrdering.compare方法的时候,会先调用NullsFirstOrdering.compare方法,再调用ReverseOrdering.compare方法

这会导致排序完毕的集合,null元素在最前面,后面则是逆向元素

比方[2,1,3,null,0]的排序结果就是[null,3,2,1,0]

这就是链式调用的特点,从右向左,逐渐应用排序规则

 

3. CompoundOrdering

Ordering的compound方法,可以在

 

Guava源码学习(二)Ordering