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方法为例 

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

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

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

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


    // Arrays.sort(a, (Comparator) c);
    public static <T> void sort(T[] a, Comparator<? super T> 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 <T> List<T> sort(List<T> list) {
        if (isNotEmpty(list)) {
            Collections.sort(list);
        }
        return list;
    }

    // Collections.sort(list)
    public static <T extends Comparable<? super T>> void sort(List<T> 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方法不同

3. 链式调用

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

3.1 reverse()

获取语义相反的排序器

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

3.2 nullsFirst()/nullsLast()

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

List<Integer> 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<Integer> list = Lists.newArrayList(1, 3, 9, 4, 7);
boolean result = Ordering.natural().isOrdered(list); // false 

4.2 greatestOf

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

List<Integer> list2 = Ordering.natural().greatestOf(list, 3);
// list2:[9,7,4]
List<Integer> 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

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Guava Ordering是一个用于排序的工具类,它为构建复杂的比较提供了一种流畅的风格。通过使用Guava Ordering,我们可以根据自定义的规则对集合中的元素进行排序。 在Guava Ordering中,有三种静态方法用于创建Ordering排序:natural()、usingToString()和from(Comparator)。natural()方法使用自然排序规则生成排序,即从小到大的顺序。usingToString()方法根据元素的toString()方法返回值进行排序。from(Comparator)方法根据给定的Comparator生成排序。 创建Ordering排序后,可以使用它对集合或元素进行操作。常见的方法包括sortedCopy(List)、immutableSortedCopy(Iterable)、min(E, E)和max(E, E)等。sortedCopy(List)方法返回一个已排序的List副本,immutableSortedCopy(Iterable)方法返回一个不可变的已排序集合,min(E, E)方法返回两个元素中较小的那个,max(E, E)方法返回两个元素中较大的那个。 下面是一个示例代码,展示了如何使用Guava Ordering对People类的age属性进行排序: List<People> peopleList = new ArrayList<People>() { { add(new People("A", 33)); add(new People("B", 11)); add(new People("C", 18)); } }; Ordering<People> ordering = Ordering.natural().onResultOf(new Function<People, Comparable>() { @Override public Comparable apply(People people) { return people.getAge(); } }); for (People p : ordering.sortedCopy(peopleList)) { System.out.println(MoreObjects.toStringHelper(p) .add("name", p.getName()) .add("age", p.getAge())); } 这段代码中,我们首先创建了一个包含People对象的List。然后使用Ordering.natural().onResultOf()方法创建了一个排序,该排序按照People对象的age属性进行排序。最后,我们通过ordering.sortedCopy()方法将集合按照排序规则进行排序,并打印排序后的结果。 通过使用Guava Ordering,我们可以轻松地实现各种排序需求,并且可以方便地链式调用方法来定制和增强现有的比较

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值