最近做算法题用了Comparator接口下的compare方法,思考了一下升序和降序的规则是如何来的,现在做一个补充,方便以后回顾。

 升序代码

    public static void main(String[] args) {
Integer[] nums = new Integer[]{6, 8, 3, 0, 2};
Arrays.sort(nums, new Comparator<Integer>() { @Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});
for (Integer i : nums) {
System.out.print(i + " ");
}
}

降序代码

    public static void main(String[] args) {
Integer[] nums = new Integer[]{6, 8, 3, 0, 2};
Arrays.sort(nums, new Comparator<Integer>() { @Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
for (Integer i : nums) {
System.out.print(i + " ");
}
}

所以更多时候我们是直接记住了compare(int o1, int o2)方法 return o1 - o2 是升序,return o2 - o1 是降序。那么原因我们不妨跳进去源码看一下

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

可以看出他是进去了else内,不妨先进入legacyMergeSort看一下

    private static <T> void legacyMergeSort(T[] a, Comparator<? super T> c) {
T[] aux = a.clone();
if (c==null)
mergeSort(aux, a, 0, a.length, 0);
else
mergeSort(aux, a, 0, a.length, 0, c);
}

这里很明显也是进去了else内,继续看mergeSort

    private static void mergeSort(Object[] src,
Object[] dest,
int low, int high, int off,
Comparator c) {
int length = high - low; // Insertion sort on smallest arrays
if (length < INSERTIONSORT_THRESHOLD) {
for (int i=low; i<high; i++)
for (int j=i; j>low && c.compare(dest[j-1], dest[j])>0; j--)
swap(dest, j, j-1);
return;
} // Recursively sort halves of dest into src
int destLow = low;
int destHigh = high;
low += off;
high += off;
int mid = (low + high) >>> 1;
mergeSort(dest, src, low, mid, -off, c);
mergeSort(dest, src, mid, high, -off, c); // If list is already sorted, just copy from src to dest. This is an
// optimization that results in faster sorts for nearly ordered lists.
if (c.compare(src[mid-1], src[mid]) <= 0) {
System.arraycopy(src, low, dest, destLow, length);
return;
} // Merge sorted halves (now in src) into dest
for(int i = destLow, p = low, q = mid; i < destHigh; i++) {
if (q >= high || p < mid && c.compare(src[p], src[q]) <= 0)
dest[i] = src[p++];
else
dest[i] = src[q++];
}
}

这一段的代码关键就是如下部分

        if (length < INSERTIONSORT_THRESHOLD) {
for (int i=low; i<high; i++)
for (int j=i; j>low && c.compare(dest[j-1], dest[j])>0; j--)
swap(dest, j, j-1);
return;
}

可以看到这里面调用了compare方法,当方法的返回值大于0的时候就将数组的前一个数和后一个数做交换。以升序为例来讲解,升序的话compare方法就 return o1 - o2,那么就是 return dest[j-1] - dest[j]。

当 dest[j-1] > dest[j] 时,就进行交换。当 dest[j-1] <= dest[j] 时位置不变,从而达到数组升序。降序也是一样的道理,就不多讲了。

Comparator的compare方法如何定义升序降序的更多相关文章

  1. TreeMap升序|降序排列和按照value进行排序

    TreeMap 升序|降序排列 import java.util.Comparator; import java.util.TreeMap; public class Main { public st ...

  2. 【java】实体类中 按照特定的字段 进行升序/降序 排序

    背景: 实际页面上  所有的分值都是按照JSON格式存储在一个字符串中 存储在同一个字段中: {"ownPTotal":"10>0","ownO ...

  3. C++员工管理系统(封装+多态+继承+分类化+函数调用+读写文件+指针+升序降序算法等一系列知识结合)

    1 C++职工管理系统 2 该项目实现 八个 功能 3 1-增加功能 2-显示功能 3-删除功能 4-修改功能 4 5-查找功能 6-排序功能 7-清空功能 8-退出功能 5 实现多个功能使用了多个C ...

  4. js学习篇--数组按升序降序排列

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. C# List.sort排序详解(多权重,升序降序)

    很多人可能喜欢Linq的orderBy排序,可惜U3D里面linq在Ios上会报错,所以就必须使用list的排序. 其实理解了并不难 升序降序比较 sort有三种结果 1,-1,0分别是大,小,相等. ...

  6. C# List.sort排序(多权重,升序降序)

    很多人可能喜欢Linq的orderBy排序,可惜U3D里面linq在Ios上会报错,所以就必须使用list的排序. 其实理解了并不难 升序降序比较 sort有三种结果 1,-1,0分别是大,小,相等. ...

  7. mysql_DML_select_升序降序去重

    select *from wsb   limit 5;显示前5行 select *from students LIMIT  (m,n) (其中m是指记录开始的index,从0开始,表示第一条记录n是指 ...

  8. Java Collection.sort 排序升序, 降序问题

    不多说,记住2点, 直接上代码(下面是降序): package mall; import java.util.ArrayList; import java.util.Collections; impo ...

  9. 快速排序:升序+降序----java实现

    快速排序思路:先把第一个元素令为low下标,最后一个为high下标.并把第一个元素令为temp来作为标准元素.以标准元素来调整数组,使比标准元素小的都在标准元素前,比标准元素大的都在标准元素后.这样一 ...

随机推荐

  1. Boa Web Server 缺陷报告及其修正方法

    综述 Boa 作为一种轻巧实用的 WEB 服务器广泛应用于嵌入式设备上, 但 Boa 对实现动态网页的 CGI  的支持上仍存在一些缺陷, 本文描述了 Boa 对 CGI 的 Status/Locat ...

  2. linux各文件夹的作用-(转自玉米疯收)

    linux下的文件结构,看看每个文件夹都是干吗用的 /bin 二进制可执行命令 /dev 设备特殊文件 /etc 系统管理和配置文件 /etc/rc.d 启动的配置文件和脚本 /home 用户主目录的 ...

  3. fragment不适用binding的加载视图方法

    abstract class BaseFragment :Fragment(){ override fun onCreateView( inflater: LayoutInflater, contai ...

  4. CVPR2020论文解析:视觉算法加速

    CVPR2020论文解析:视觉算法加速 GPU-Accelerated Mobile Multi-view Style Transfer 论文链接:https://arxiv.org/pdf/2003 ...

  5. Angel图算法

    Angel图算法 [2.0]CommonFriends 计算两个好友的共同好友数,某种程度上可以刻画两个节点之间的紧密程度. 输入 输入数据路径:输入文件所在路径,无权网络数据, 数据格式为两列 sr ...

  6. deeplearning算法优化原理

    deeplearning算法优化原理目录· 量化原理介绍 · 剪裁原理介绍 · 蒸馏原理介绍 · 轻量级模型结构搜索原理介绍 1. Quantization Aware Training量化介绍1.1 ...

  7. Bayer滤镜转换颜色方案

    Bayer滤镜如何转换颜色? Bayer模式是颜色模式,被广泛应用于CCD和CMOS摄像头.相机使用了拜耳滤镜,分别过滤得到红绿蓝三种颜色.既然要得到的是红绿蓝频段光线的强度,要通过的就是红绿蓝光,就 ...

  8. spring 声明式事务剖析

    spring事务是在数据库事务的基础上进行封装扩展, 支持原有事务的隔离级别, 加入了事务传播的概念,提供多个事务合并和分割的功能, 提供声明式事务,让事务和业务代码分开 spring提供了三个接口供 ...

  9. 工作流中容器化的依赖注入!Activiti集成CDI实现工作流的可配置型和可扩展型

    Activiti工作流集成CDI简介 activiti-cdi模块提供activiti的可配置型和cdi扩展 activiti-cdi的特性: 支持 @BusinessProcessScoped be ...

  10. 深入理解java虚拟机笔记Chapter4

    JDK命令行工具 其中的重中之重是 jstat 命令!而它最常用的参数就是 -gcutil,使用格式如下: jstat -gcutil [pid] [intervel] [count] 输出如下 D: ...