Java中的集合排序算法

1.  引言

排序是一个 Java 开发者,在日常开发过程中随处可见的开发内容,Java 中有丰富的 API 可以调用使用。在 Java 语言中,作为集合工具类的排序方法,必定要做到通用、高效、实用这几点特征。使用什么样排序算法会比较合适,能够做到在尽量降低时间、空间复杂度的情况下,又要兼顾保证稳定性,达到优秀的性能。可能从性能角度出发首先会想到的是快速排序,或者归并排序。作为 jdk 提供的通用排序功能,使用又如此频繁,肯定有独特之处,一起来看学习下期中的奥秘。

文中不会过多的介绍几大基本排序算法的方式、由来和思想,主要精力集中在一块探讨 java 中排序方法所使用的算法,以及那些是值得我们学习和借鉴的内容。文中如有理解和介绍的错误,一起学习,一起探讨,一起进步。

2.  案例

日常使用最为频繁的排序,莫过于如下代码案例,给定一个现有的序列进行一定规则下的排序,配合 java8 的 stream 特性,可以很方便的对一个集合进行排序操作(排序规则只是对排序对象及排序方案的限定,不在本文讨论范围内)。

List<Integer> list = Arrays.asList(10, 50, 5, 14, 16, 80);System.out.println(list.stream().sorted().collect(Collectors.toList()));

在代码执行的过程中 SortedOps.java 类中 Arrays.sort(array, 0, offset, comparator); 执行了 Array 集合类型的 sort 排序算法。

@Overridepublic void end() {
      Arrays.sort(array, 0, offset, comparator);    downstream.begin(offset);    if (!cancellationWasRequested) {
          for (int i = 0; i < offset; i++)            downstream.accept(array[i]);    }    else {
          for (int i = 0; i < offset && !downstream.cancellationRequested(); i++)            downstream.accept(array[i]);    }    downstream.end();    array = null;}

如果使用 Collections.sort() 方法如下打印 list1 和 list2 结果一样,且调用的都是 Arrays 集合类中的 sort 方法。

List<Integer> list1 = Arrays.asList(10, 50, 5, 14, 16, 80);System.out.println(list1.stream().sorted().collect(Collectors.toList()));
List<Integer> list2 = Lists.newArrayList();list2.addAll(list1);Collections.sort(list2);System.out.println(list2);// 输出:// [5, 10, 14, 16, 50, 80]// [5, 10, 14, 16, 50, 80]

2.  Collections.sort 方法介绍

Collections 类中关于 sort 方法定义如下:

public static <T extends Comparable<? super T>> void sort(List<T> list) {
      list.sort(null);}

通过该方法注释,查看到有三项值得关注的信息,大概意思是该方法实现了稳定且默认升序排序的功能。

1. Sorts the specified list into ascending order, according to the Comparable natural ordering of its elements.2. This sort is guaranteed to be stable equal elements will not be reordered as a result of the sort.3. The specified list must be modifiable, but need not be resizable.

进入 sort,代码进入到 List 类的 sort 方法,发现方法将入参 list 先转为了数组 Object[],之后利用 Arrays.sort 进行排序。

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);    }}

首先在这里思考一个问题为什么要转为数组,问题答案已经在方法的英文注释中说明白了。

* The default implementation obtains an array containing all elements in* this list, sorts the array, and iterates over this list resetting each* element from the corresponding position in the array. (This avoids the* n<sup>2</sup> log(n) performance that would result from attempting* to sort a linked list in place.)

是为了避免直接对 List<T>的链表进行排序,从而耗费 O(n2logn) 时间复杂度。当然这里在 this.toArray()时,为了将 list 强行变为数组会损失一些性能和空间开销,源码中使用了 System.arraycopy 调用底层操作系统方法进行数据复制,详细内容可以查看相关实现。 继续进入 Arrays 类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值