guava排序器Ordering

目录

1. 排序器的创建

2. 剖析与原生排序的区别

3. 链式调用

3.1 reverse()

3.2 nullsFirst()/nullsLast()

4 运用排序器

4.1 isOrdered

4.2 greatestOf

4.3 min/max


排序器Ordering,是Guava流畅风格比较器[Comparator]的实现,它可以用来为构建复杂的比较器,以完成集合排序的功能。

1. 排序器的创建

Ordering静态创建排序器

方法 描述
natural() 对可排序类型做自然排序,如数字按大小,日期按先后排序
usingToString() 按对象的字符串形式做字典排序[lexicographical ordering]
from(Comparator) 把给定的Comparator转化为排序器

以natural方法为例 

guava排序器Ordering_第1张图片

2. 剖析与原生排序的区别

以natural方法为例,剖析dubbo提供的集合工具类和guava排序器的区别

list.sort(Ordering.natural()); //源码分析

    // list.sort(Ordering.natural())
    default void sort(Comparator c) {
        Object[] a = this.toArray();
        Arrays.sort(a, (Comparator) c);
        ListIterator i = this.listIterator();
        for (Object e : a) {
            i.next();
            i.set((E) e);
        }
    }


    // Arrays.sort(a, (Comparator) c);
    public static  void sort(T[] a, Comparator c) {
        if (c == null) {
            sort(a);
        } else {
            if (LegacyMergeSort.userRequested)
                legacyMergeSort(a, c);
            else
                TimSort.sort(a, 0, a.length, c, null, 0, 0);
        }
    }

CollectionUtils.sort(list); //源码分析 

    // CollectionUtils.sort(list)
    public static  List sort(List list) {
        if (isNotEmpty(list)) {
            Collections.sort(list);
        }
        return list;
    }

    // Collections.sort(list)
    public static > void sort(List list) {
        list.sort(null);
    }

可见,CollectionUtils.sort只是包了一层,底层也是调用了list.sort方法,只是比较器为null

再往下看,可看到排序时的比较核心代码,guava的方式是使用自己实现Comparator的compare方法去比较,而dubbo提供的集合工具类则是通过类本身实现的compareTo方法去比较

// list.sort(Ordering.natural())
c.compare(a[runHi], a[runHi - 1]) < 0

// CollectionUtils.sort(list)
(Comparable) a[runHi]).compareTo(a[runHi - 1]) < 0

Integer类实现的compareTo方法如下

    public int compareTo(Integer anotherInteger) {
        return compare(this.value, anotherInteger.value);
    }

    public static int compare(int x, int y) {
        return (x < y) ? -1 : ((x == y) ? 0 : 1);
    }

guava的Ordering排序起实现了Comparator,实现了compare方法,但实际上在本例子Integer类型的排序中,NaturalOrdering的比较方法最终用的还是Integer类的compareTo方法

  @Override
  public abstract int compare(@Nullable T left, @Nullable T right);

  // NaturalOrdering
  @Override
  public int compare(Comparable left, Comparable right) {
    checkNotNull(left); // for GWT
    checkNotNull(right);
    return left.compareTo(right);
  }

每种排序器实现的compare方法不同

guava排序器Ordering_第2张图片

3. 链式调用

通过链式调用,可以由给定的排序器衍生出其它排序器

3.1 reverse()

获取语义相反的排序器

list.sort(Ordering.natural().reverse()); // 9,7,4,3,1

3.2 nullsFirst()/nullsLast()

使用当前排序器,并将null值放在最前面/最后面。若排序列表中有null值,用原生排序会报空指针异常

List list = Lists.newArrayList(1, 3, 9, null, 4, 7);

list.sort(Ordering.natural().nullsFirst()); // list:[null,1,3,4,7,9]

list.sort(Ordering.natural().nullsLast()); // list:[1,3,4,7,9,null]

当阅读链式调用产生的排序器时,应该从后往前读。之所以要从后往前读,是因为每次链式调用都是用后面的方法包装了前面的排序器。例如上面,是先将null值放在列表最前面,再去自然排序。

运用排序器

Guava的排序器实现有若干操纵集合或元素值的方法

4.1 isOrdered

判断可迭代对象是否已按排序器排序:允许有排序值相等的元素。

List list = Lists.newArrayList(1, 3, 9, 4, 7);
boolean result = Ordering.natural().isOrdered(list); // false 

4.2 greatestOf

获取可迭代对象中前的k个元素。

List list2 = Ordering.natural().greatestOf(list, 3);
// list2:[9,7,4]
List list3 = Ordering.natural().reverse().greatestOf(list, 3);
// list3:[1,3,4]

4.3 min/max

获取最大最小值

Integer max = Ordering.natural().max(list);// 9
Integer min = Ordering.natural().min(list);// 1

 

你可能感兴趣的:(Java)