作者 | TrueDei

责编 | 王晓曼

出品 | CSDN博客

前言

排序是在程序开发中最常用到的,最常见的就是针对一些数字进行排序。而现实中像商品的名字,订单的日期等进行排序。Java的JDK中就自带了Comparable接口,那么来看下这个,如何与面试官对答如流。

抛下 Arrays.sort() 中排序的算法,一起来揭开这层面纱吧。

1、猜一猜

猜测以下代码的执行结果是什么?

int[] ints = {50,1,4,8,3};
String [] strings = {"q","a","c"};
Arrays.sort(ints);for (String val: strings) {System.out.print(val + " ");
}System.out.println();for (int i = 0; i < ints.length; i++) {System.out.print(ints[i]+" ");
}

好了,现在猜测结束。

你会很快猜到一下内容:

q a c
1 3 4 8 50

你可真是一个小能能,厉害的不要不要的。

但是,如果面试官问你:

为什么 int 数组, String 数组等等,这些可以使用 Arrays.sort() 进行排序呢?

咱们慢慢揭晓这个答案。

先看几个源代码:

1、Integer的源代码

public final class Integer extends Number implements Comparable<Integer> {...............public int compareTo(Integer anotherInteger) {return compare(this.value, anotherInteger.value);}
}

2、Short的源代码

public final class Short extends Number implements Comparable<Short> {...............public int compareTo(Short anotherShort) {return compare(this.value, anotherShort.value);}}

3、String的源代码

public final class Stringimplements java.io.Serializable, Comparable<String>, CharSequence {...............public int compareTo(String anotherString) {int len1 = value.length;int len2 = anotherString.value.length;int lim = Math.min(len1, len2);char v1[] = value;char v2[] = anotherString.value;int k = 0;while (k < lim) {char c1 = v1[k];char c2 = v2[k];if (c1 != c2) {return c1 - c2;}k++;}return len1 - len2;}}

发现了什么?

是不是发现了都实现了Comparable接口和compareTo方法。

对,你现在也许知道怎么去回答面试官这个问题了,因为他们都实现了Comparable接口和compareTo方法。

3、试试真是如此吗?不信测试一下

新建二个实体类和一个测试类,一个是Student实体类,一个是User实体类,一个是测试类Test。

Student类

为了方便演示,这里的Student类实现Comparable接口。

package ComparableInterface;/*** @Auther: truedei* @Date: 2020 /20-5-7 20:29* @Description:*/
public class Student implements Comparable<Student>{private int age;private String name;public Student() {}public Student(int age, String name) {this.age = age;this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Student{" +"age=" + age +", name='" + name + '\'' +'}';}@Overridepublic int compareTo(Student o) {return this.getAge() - o.getAge();}
}

User类

为了方便演示,这里的User类不实现Comparable接口。

package ComparableInterface;/*** @Auther: truedei* @Date: 2020 /20-5-7 20:29* @Description:*/
public class User{private int age;private String name;public User() {}public User(int age, String name) {this.age = age;this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "User{" +"age=" + age +", name='" + name + '\'' +'}';}}

测试类

package ComparableInterface;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;/*** @Auther: truedei* @Date: 2020 /20-5-7 20:29* @Description:*/
public class Test {public static void main(String[] args) {}
}

测试1、比较Student类

Student s1 = new Student(19,"张三");
Student s2 = new Student(18,"李四");int i = s1.compareTo(s2);
if(i>=0){System.out.println(s1.getName()+"年龄大");
}else{System.out.println(s2.getName()+"年龄大");
}

测试结果1:

这个结果也是很容易猜到的,因为Student类实现了Comparable接口,并实现了 compareTo方法。并且是以age做比较的。

张三年龄大

测试2、比较User类

        User u1 = new User(12,"王五");User u2 = new User(22,"赵六");int j = u1.compareTo(u2);if(j>=0){System.out.println(u1.getName()+"年龄大");}else{System.out.println(u2.getName()+"年龄大");}

测试2的结果:

这个是没有结果的,因为程序是无法执行的,会报出没有compareTo这个方法。

原因:

原因很简单,因为没有实现Comparable接口。

测试3、对Student类的数组排序

随便添加进去几个数据,为了方便理解,我就写的稍微麻烦了一点。

        Student s1 = new Student(19,"张三");Student s2 = new Student(18,"李四");Student s3 = new Student(2,"王五");Student[] students = {s1,s2,s3};System.out.println("排序前:");for (Student st:students) {System.out.println(st.toString());}System.out.println();//进行排序Arrays.sort(students);System.out.println("排序后:");for (Student st:students) {System.out.println(st.toString());}

测试结果:

是不是有点小惊喜?为什么可以进行直接排序呢?

没错,就是因为实现了那个Comparable接口,而且是根据年龄的大小来排序的。

排序前:
Student{age=19, name='张三'}
Student{age=18, name='李四'}
Student{age=2, name='王五'}排序后:
Student{age=2, name='王五'}
Student{age=18, name='李四'}
Student{age=19, name='张三'}

如果你想从大到小排序怎么办?

也很简单,只需要改变一下compareTo中的方法即可。

修改如下:

    @Overridepublic int compareTo(Student o) {
//        return this.getAge() - o.getAge();return o.getAge()- this.getAge();}

为了好看,我把三个Student类的数据,修改了一下:

Student s1 = new Student(7,"张三");
Student s2 = new Student(18,"李四");
Student s3 = new Student(2,"王五");

测试结果:

排序前:
Student{age=7, name='张三'}
Student{age=18, name='李四'}
Student{age=2, name='王五'}排序后:
Student{age=18, name='李四'}
Student{age=7, name='张三'}
Student{age=2, name='王五'}Process finished with exit code 0

测试4、对User类的数组排序

可以先猜测一下,可能排序吗?

        User u1 = new User(12,"王五");User u2 = new User(22,"赵六");User u3 = new User(15,"杂七");User[] users = {u1,u2,u3};System.out.println("排序前:");for (User user:users) {System.out.println(user.toString());}System.out.println();//进行排序Arrays.sort(users);System.out.println("排序后:");for (User user:users) {System.out.println(user.toString());}

测试结果:

排序前:
User{age=12, name='王五'}
User{age=22, name='赵六'}
User{age=15, name='杂七'}Exception in thread "main" java.lang.ClassCastException: ComparableInterface.User cannot be cast to java.lang.Comparableat java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:320)at java.util.ComparableTimSort.sort(ComparableTimSort.java:188)at java.util.Arrays.sort(Arrays.java:1246)at ComparableInterface.Test.main(Test.java:54)

提示你:

cannot be cast to java.lang.Comparable

说明:无法转换成Comparable

那么就得出结论:

没有实现Comparable接口的类的数组是无法使用Arrays.sort()进行排序的

改造 User类 进一步测试

稍微改造一下:给User类实现Comparable接口。

1、需求如下

因为User类有年龄和姓名,年龄小的优先。

如果年龄相同,那么比较姓名,按姓名的ascii码值来排序,例如:a-b-c

2、修改User类

package ComparableInterface;/*** @Auther: truedei* @Date: 2020 /20-5-7 20:29* @Description:*/
public class User implements Comparable<User>{private int age;private String name;public User() {}public User(int age, String name) {this.age = age;this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "User{" +"age=" + age +", name='" + name + '\'' +'}';}@Overridepublic int compareTo(User o) {//年龄从小到大if(this.getAge() - o.getAge() > 0){return 1;}else if(this.getAge() - o.getAge() == 0){return this.getName().compareTo(o.getName());}return -1;}
}

重点是:

  • 可以看到年龄是从小到大的对比

  • 如果this.年龄 - o.年龄 == 0 说明相等,那么就比较名字

@Override
public int compareTo(User o) {//年龄从小到大if(this.getAge() - o.getAge() > 0){return 1;}else if(this.getAge() - o.getAge() == 0){return this.getName().compareTo(o.getName());}return -1;
}

3、测试

为了方便理解,我把姓名修改成了a,e,s,q,d,g这些字母

为了比较好说明,我找了一个比较简洁的ascii码表:

我们拿a、b、y做为姓名来测试:

System.out.println("a="+(int)'a');
System.out.println("b="+(int)'b');
System.out.println("y="+(int)'y');

结果:

97<98<121

a<b<y

a=97
b=98
y=121

正式代码:

        User u1 = new User(12,"b");User u2 = new User(22,"y");User u3 = new User(22,"a");User[] users = {u1,u2,u3};System.out.println("排序前:");for (User user:users) {System.out.println(user.toString());}System.out.println();//进行排序Arrays.sort(users);System.out.println("排序后:");for (User user:users) {System.out.println(user.toString());}

测试结果:

排序前:
User{age=12, name='b'}
User{age=22, name='y'}
User{age=22, name='a'}排序后:
User{age=12, name='b'}
User{age=22, name='a'}
User{age=22, name='y'}

版权声明:本文为CSDN博主「TrueDei」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:

https://truedei.blog.csdn.net/article/details/105981691

【END】

更多精彩推荐☞中国 AI 应用元年来了!
☞年仅 5 岁的 Rust 如何成为最受欢迎的编程语言?
☞15 岁黑进系统,发挑衅邮件意外获 Offer,不惑之年捐出全部财产,Twitter CEO 太牛了!
☞避坑!使用 Kubernetes 最易犯的 10 个错误
☞必读!53个Python经典面试题详解
☞赠书 | 1月以来 Tether 增发47亿 USDT,美元都去哪儿了?
你点的每个“在看”,我都认真当成了喜欢

Arrays.sort() 为什么可以对 int 等数组进行排序?我跟面试官扯了半个小时 | 原力计划...相关推荐

  1. vue 数组 指定位置添加数据_VUE 响应式原理源码:带你一步精通 VUE | 原力计划...

    作者 | 爱编程的小和尚 责编 | 王晓曼 出品 | CSDN博客 学过 VUE 如果不了解响应式的原理,怎么能说自己熟练使用 VUE,要是没有写过一个简易版的 VUE 怎么能说自己精通 VUE,这篇 ...

  2. Java JDK 自带排序(Arrays.sort(数组名))与自行编写的降序

    JDK 自带排序(Arrays.sort(数组名))与自行编写的降序 jdk 自带的排序 Arrays.sort(数组名) 只能进行升序排列 可以与自己写的降序 配合使用 import java.ut ...

  3. Arrays.sort排二维数组

    int[][] intervals=new int[100][2]; 方法一: Arrays.sort(intervals,new Comparator<int[]>(){public i ...

  4. Java Arrays.sort()的几种用法

    Java的Arrays类中有一个sort()方法,该方法是Arrays类的静态方法,在需要对数组进行排序时,非常的好用. 但是sort()的参数有好几种,下面我就为大家一一介绍,这几种形式的用法. = ...

  5. Java的Arrays.sort()良心总结

    C语言的stilib.h头文件中有qsort(),C++的STL库中有sort(),这些封装好的排序函数让我们避免了比赛手写排序,给我们解题带来了的便利.在Java的Arrays类中也封装好了类似的方 ...

  6. arrays.sort(._Arrays.hashCode(Object [])与Objects.hash(Object…)

    arrays.sort(. 从JDK 1.5开始 , Arrays类提供了名为" hashCode "的重载static方法. 大多数重载方法都接受特定原始类型的数组,但是Arra ...

  7. java集合中中文排序_利用Collator和Collections.sort对list进行中文排序,注意与Arrays.sort的区别...

    //两者的关系:1.Coollections.sort的内部实现是用Arrays.sort来实现的. //2.如果要排序的list中的对象已经实现了Comparable接口,那么可以用Arrays.s ...

  8. bucket sort sample sort 并行_Java 中 Arrays.sort 和 Arrays.parallelSort 哪个更快?

    1. 概述 我们都使用过 Arrays.sort() 对对象或原始数据类型数组(byte,short,int,long,char,float,double和boolean)进行排序.在 JDK 8 中 ...

  9. Arrays.sort与Arrays.parallelSort区别

    概述 我们都使用过 Arrays.sort() 对对象或原始数据类型数组(byte,short,int,long,char,float,double和boolean)进行排序.在 JDK 8 中,创造 ...

最新文章

  1. DeepKey:科学家提出一种基于脑纹独特性的多模态生物识别系统可以防范身份欺骗...
  2. MacroMedia FreeHand中文版
  3. Spring-依赖注入
  4. 【机器学习】一位机器学习高手的个人技术书目
  5. pycharm替换和查找文件中所有相同代码方法
  6. 可能是全网首个前端源码共读活动,诚邀加入学习
  7. Angular项目打包到nginx部署过程
  8. java for i i 区别,i ++amp;和i ++之间的区别是什么? ++我在for循环(Java)?
  9. 【转】全了!临港四镇最新对口地段小学,中学都在这里,看看你的孩子能读哪个学校
  10. oracle查看序列数据语法,oracle查询各种数据字典的语法
  11. jquery ajax json传递数组,jQuery ajax 传递JSON数组到Spring Controller
  12. Ubuntu下华为方舟编译器环境安装
  13. matlab 韦布尔拟合,MATLAB数据拟合工具在数学建模中的简单应用
  14. 网络管理之SNMP协议
  15. 个人微信api接口调用-转账发红包
  16. 计算机网络驱动坏了怎么解决办法,网卡驱动异常怎么办_网卡驱动异常解决办法_飞翔教程...
  17. 基于QT和DCMTK的Dicom 图像浏览器---收尾三
  18. (数据结构)栈(LIFO结构)——概念、进栈、出栈、先进后出的特性
  19. 常用的maven命令
  20. mysqldump导出所有数据库数据

热门文章

  1. BZOJ2142: 礼物
  2. SpringBoot入坑-请求参数传递
  3. java:数据库连接池
  4. springmvc.xml或spring.xml 能运行配置文件总是出现错误
  5. Spring配置 context:component-scan/ mvc:annotation-driven /
  6. adb shell 查找并删除文件
  7. Javascript脚本 : eval()函数
  8. MSSql与MYSQL比较
  9. linux迭代同步文件,Linux Shell——迭代循环
  10. 写出一下Java方法对应的签名_Java中的方法签名是否包含其返回类型?