最近做算法题用了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. 分布式存储ceph---ceph osd 故障硬盘更换(6)

    正常状态: 故障状态: 实施更换步骤: 1.关闭ceph集群数据迁移: osd硬盘故障,状态变为down.在经过mod osd down out interval 设定的时间间隔后,ceph将其标记为 ...

  2. VFB FEEDBACK

  3. 矩阵中的路径 DFS+剪枝

    给定一个 m x n 二维字符网格 board 和一个字符串单词 word .如果 word 存在于网格中,返回 true :否则,返回 false . 单词必须按照字母顺序,通过相邻的单元格内的字母 ...

  4. Step By Step(Lua字符串库)

    Step By Step(Lua字符串库) 1. 基础字符串函数:    字符串库中有一些函数非常简单,如:    1). string.len(s) 返回字符串s的长度:    2). string ...

  5. CUDA上深度学习模型量化的自动化优化

    CUDA上深度学习模型量化的自动化优化 深度学习已成功应用于各种任务.在诸如自动驾驶汽车推理之类的实时场景中,模型的推理速度至关重要.网络量化是加速深度学习模型的有效方法.在量化模型中,数据和模型参数 ...

  6. Structured Streaming编程 Programming Guide

    Structured Streaming编程 Programming Guide Overview Quick Example Programming Model Basic Concepts Han ...

  7. 5G和AI机器人平台为工业4.0和无人机提供服务

    5G和AI机器人平台为工业4.0和无人机提供服务 Qualcomm 5G and AI robotics platform delivers for Industry 4.0 and drones 高 ...

  8. C# & JS 判断字符串是否为日期格式

    在C#中,对格式的判断有一类专门函数,那就是TryParse.TryParse在各个不同的类型类(如int,string,DateTime)中,都是存在的.在TryParse中一般有两个参数,一个是待 ...

  9. Django(63)drf权限源码分析与自定义权限

    前言 上一篇我们分析了认证的源码,一个请求认证通过以后,第二步就是查看权限了,drf默认是允许所有用户访问 权限源码分析 源码入口:APIView.py文件下的initial方法下的check_per ...

  10. fiddler概念及原理

    一.什么是fiddler? fiddler是位于客户端与服务器端的HTTP代理,它能够记录客户端与服务器之间所有的HTTP请求,可以针对特定的HTTP请求,分析请求数据,设置断点,调试WEB应用,修改 ...