Java中Arrays的sort排序原理
⼀、简要介绍
Arrays⾥我们⽤的⽐较多的就是sort函数,这⾥我写⼀点我的学习过程。
sort函数本⾝的排序性能是⽐较⾼的,它会在不同情况下运⽤不同的排序⽅法,如快排、⼆叉排,它给出了默认的从⼩到⼤的排序,同时也提供了⾃定义的排序⽅法,这⾥我会从基本数据类型的排序和⾃⼰创建对象进⾏排序来说明。(JDK版本为11)sort函数 js
⼆、基本数据类型的默认排序
1. int型
基本代码
这个的排序结果就是默认的从⼩到⼤排序,我们追sort的原码:
点击查看代码
发现它其实就是调⽤了⼀个sort(int[]a),其中调⽤了DualPivotQuicksort的sort⽅法,这个静态类的sort⽅
法其实是很多种排序⽅法的⼀个综合,由于我是初学,这⾥不讲解,可以参考blog.csdn/lyj1597374034/article/details/106720629 这篇⽂章,具体意思就是DualPivotQuicksort**会根据不同的场景合适的调⽤不同的排序⽅法**
2. char型
我将上述代码⾥⾯的类型改为char,发现调⽤的还是同⼀个⽅法,这个⽅法的参数可以有很多种,基本上默认的数据类型都可以⽤,剩下的数据类型我就不⼀⼀举例。
点击查看代码
三、基本数据类型的⾃定义排序
Java⾥⾯的sort函数提供了⼀个Comparator接⼝使⽤户能够⾃定义排序顺序,如果需要⾃⼰定义排序顺序,需要实现⼀下Comparator接⼝,如图所⽰:
可以看到sort这⾥可以接受两个参数,第⼀个是待排序的数组,第⼆个是⼀个Comparator接⼝。
我们拿字符数组排序来举例⼦:
点击查看代码
这是⼀个完整的⾃定义排序程序,我们使⽤内部类的形式实现了Comparator接⼝,可以看到再实现了Comparator接⼝中我们要实现它的compare的⽅法,这个⽅法就是我们⾃定义排序的关键,它有两个参数,两个char类型的封装类型的变量,⽽我们的返回值是⼀个int型,这是为什么?
下⾯我们来详细说明:
1、为什么compare的参数是两个封装类型?
我们这⾥追⼀下源码:
public static <T> void sort(T[] a, Comparator<? super T> c)
这是sort⽅法的真实样⼦,可以看见它利⽤范型,严格规定来传⼊参数的类型,这⾥我们可以⼤概看出为什么要传⼊对象类型,那这⾥我可以省略吗?当然可以!如果省略,这⾥默认你传⼊的是⼀个Object对象,代码如下:
点击查看代码
可以看到我这⾥没有指定范型,o1和o2两个对象就是Objiect类型,则在返回的时候需要进⾏强制类型转换。因此在我们排序不同类型的序列时,应该传⼊对应的封装类型或者对象类型。这是⾃定义排序的基本条件,同时定义数组的时候也需要讲定义类型改变为封装类型,如:
Character[] help = new Character[]{'e','b','e','x','p','c','a'};
2、为什么我们的返回值是两个对象相减,这⾥我们继续追原码:
这是sort函数的全貌,可以看到,当我们传⼊的数组不为0时,真正起排序作⽤的是TimSort.sort(),因为sort会根据传⼊待排序数组的类型,长度等进⾏合适的选择,还有更多的__Sort对象含有这个sort⽅法,⽽我们的例⼦这⾥调⽤的是TimSort⾥⾯的sort⽅法
点击查看代码
我们直接进⼊真正⾏使排序功能的代码:
点击查看代码
本⽂不关⼼如何排序,我们着重看compare⽅法起了什么作⽤,注意看这两句代码:
if (cpare(a[runHi++], a[lo]) < 0)
while (runHi < hi && cpare(a[runHi], a[runHi - 1]) >= 0)
可以看到这⾥直接调⽤了我们所实现的compare⽅法,⽤来进⾏排序⾥⾯的判断,这⾥真正的原理清楚了,原来我们返回的值可以直接影响到整个排序的进程,⽽返回值的正负是判断的关键,所以compare的返回值返回的是⼀个int型:
点击查看代码
这⾥虽然返回的是两个char的封装对象相减,但在计算的时候会⾃动解封装,转换为两个实数相减,最后返回⼀个int型的变量,解封装源码:
点击查看代码
返回的int值的正负影响到真正的排列顺序,⽽我们想要改变排列顺序就很简单,转换⼀下o1和o2的顺序即可,让返回正数的情况返回负数。基本上⾃定义排序的原理就在于此,那我们是否可以⾃⼰来实现这样的原理,当然可以!下⾯我⽤冒泡排序来演⽰⼀下。
四、⾃⼰实现⾃定义排序的原理(利⽤冒泡排序)
点击查看代码
可以看到我们利⽤了我们⾃⼰实现的compare⽅法对冒泡排序中的判断条件进⾏了⼲预,造成了我们可以利⽤o1和o2的顺序来对最后的排序结果进⾏⼲预,核⼼就是下⾯的代码:
if(compare(a[j],a[j+1]) > 0)
public static int compare(int o1,int o2){ return o1-o2; }

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。