第9版《Java核心技术卷Ⅰ》的第607页介绍了一个方法:

Collections类中的sort方法可以对实现了List接口的集合进行排序。这个方法假定列表元素实现了Comparable接口。

  查看Java官方文档可知,sort方法有两种重载形式。第一种重载是:

static <T extends Comparable<? super T>> void sort(List<T> list)

  根据官方文档的描述,这个方法将列表元素进行升序排序,但是列表要满足以下条件:
  1.列表元素实现了Comparable接口,且任意两个列表元素都是可比的。
  2.列表必须支持set方法。
  如果要通过这个方法来完成我上面提到的作业,那显然是行得通的:整数可以进行相互比较,第一个条件满足;把10个整数放入一个ArrayList或LinkedList中,这两个列表都支持set方法,第二个条件满足。实现代码如下:

import java.util.*;
public class Sort {public static void main(String[] args) {Scanner scan = new Scanner(System.in);List<Integer> list = new ArrayList<>();          //用户输入10个整数System.out.println("请输入10个整数:");for(int i = 0; i < 10; i++)                      {list.add(scan.nextInt());}scan.close();//排序Collections.sort(list);//输出排序结果System.out.println(list);}}

  程序运行结果如下:

用sort进行升序排序

  用sort方法可以很方便地实现升序排序,但能否进行降序排序?答案是肯定的,《Java核心技术卷Ⅰ》中介绍了一种用sort进行降序排序的简洁方法。这种方法需要用到sort方法的第二种重载形式:

public static <T> void sort(List<T> list,Comparator<? super T> c)

  如果想采用其他方式进行排序,那么可将一个Comparator对象作为sort方法的第二个参数。当要进行逆序排序时,最简便的方法是将Collections.reverseOrder()作为第二个参数。

import java.util.*;
public class Sort {public static void main(String[] args) {Scanner scan = new Scanner(System.in);List<Integer> list = new ArrayList<>();          //用户输入10个整数System.out.println("请输入10个整数:");for(int i = 0; i < 10; i++)                      {list.add(scan.nextInt());}scan.close();//逆序排序Collections.sort(list,Collections.reverseOrder());//输出排序结果System.out.println(list);}}

  程序运行结果如下:

用sort进行降序排序

更进一步:排序对象不是基本数据类型

  在上面的例子中,列表中的元素是整数,所以排序逻辑是很显然的:如果是升序排序,那就小数在前,大数在后。但是,如果排序的对象并非属于整数、浮点数之类的基本数据类型,那么这些对象之间的“大小”关系该如何定义?假设有这样一道题:

定义一个点类,其中有整型属性x和y,代表其坐标;除了这两个属性以外没有其他属性。随机产生10个点,并按照这些点与原点(0,0)之间的距离大小对点进行降序排序。

  如果仍想通过sort方法进行排序的话,首先点类就必须满足上面曾经提过的约束条件:点对象是可比的,因此点类必须实现Comparable接口。查看官方文档可知,Comparable接口中只有一个方法:

int compareTo(T o)

  调用这个方法的对象将会与参数o进行比较,小于o、等于o和大于o分别对应的返回值为负数、0和正数。对象之间相对大小的判断方法是自定义的,在这个问题中,就是通过比较各点与原点之间的距离来判断大小,所以点类的实现如下:

class Point implements Comparable<Point>{private int x;private int y;public Point(int x,int y){this.x = x;this.y = y;}@Override//如果该点到原点的距离大于o点到原点的距离,则该点大于o点public int compareTo(Point o) {int distance1 = (this.x) * (this.x) + (this.y) * (this.y);int distance2 = (o.x) * (o.x) + (o.y) * (o.y);return (distance1 > distance2) ? 1 : ((distance1 == distance2) ? 0 : -1); }@Overridepublic String toString() {return "(" + x + ","+  y + ")";}
}

  因为要进行降序排序,所以可以通过将Collections.reverseOrder()作为sort方法的第二个参数来实现:

public class SortDemo {private static List<Point> list = new ArrayList<>();public static void main(String[] args) {//随机生成10个点for(int i = 0; i < 10; i++){//点的坐标取值在[1,20]之间int x = (int)(Math.random() * 20) + 1;int y = (int)(Math.random() * 20) + 1;list.add(new Point(x,y));}System.out.print("排序前:");System.out.println(list);//降序排序Collections.sort(list,Collections.reverseOrder());System.out.print("排序后:");System.out.println(list);}}

  程序结果如下:

对点进行降序排序

  现在对sort方法进行小结:

  实现了Comparable接口的类都可以用sort方法进行排序,默认的排序方法是升序;如果想进行降序排序,只需把Collections.reverseOrder作为第二个参数传给sort方法。

了解Comparator接口

  上面反复提到的Collections.reverseOrder方法返回的是一个Comparator对象。其实Comparator接口并不陌生,常用的equals方法就来自这个接口。Comparator接口用来定义两个对象之间的比较方法,它有一个叫做compare的方法,函数签名如下:

int compare(T o1,T o2)

   o1 > o2,返回正数;o1 = o2,返回0;o1 < o2,返回负数。
  从前面的例子可以看出,可以使用Comparator对象来控制sort的排序方法,这是如何实现的?查看sort方法的相关源码,我发现其中有这样一段代码:

sort方法的相关源码

  注意看图中用红线框起来的部分。经分析可知,这段代码实现了这样的逻辑:如果compare的返回值为正数,就交换进行比较的两个元素的位置。于是可以得出这样一个结论,如果让 x > y 时compare(x,y)返回正数,那么交换 x 和 y 的位置后大的元素在后,这就实现了升序排序;反之,如果让 x < y 时compare(x,y)返回正数,那么交换位置后小的元素在后,这就实现了降序排序。这就是Comparator对象控制排序方式的原理。

Comparator对象控制排序方式的原理

  通过Comparator对象来实现点对象的降序排序,一种可行的实现方式如下:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;//点类
class Point {private int x;private int y;public Point(int x,int y){this.x = x;this.y = y;}public int getX() {return x;}public int getY() {return y;}@Overridepublic String toString() {return "(" + x + ","+  y + ")";}
}public class SortDemo {private static List<Point> list = new ArrayList<>();public static void main(String[] args) {//随机生成10个点for(int i = 0; i < 10; i++){//点的坐标取值在[1,20]之间int x = (int)(Math.random() * 20) + 1;int y = (int)(Math.random() * 20) + 1;list.add(new Point(x,y));}System.out.print("排序前:");System.out.println(list);//降序排序Collections.sort(list,new Comparator<Point>() {@Override//当 o1 < o2 时返回正数public int compare(Point o1, Point o2) {int distance1 = (o1.getX()) * (o1.getX()) + (o1.getY()) * (o1.getY());int distance2 = (o2.getX()) * (o2.getX()) + (o2.getY()) * (o2.getY());return (distance1 < distance2) ? 1 : ((distance1 == distance2) ? 0 : -1); }});System.out.print("排序后:");System.out.println(list);}}

  程序运行结果如下:

通过实现Comparator接口来进行降序排序

  注意,在上面的程序中Point类并没有实现Comparable接口,这是因为已经通过实现Comparator接口来定义Point对象的比较方法,所以也就无需实现Comparable接口。

Collections.sort(list,new Comparator<Point>() {@Overridepublic int compare(Point o1, Point o2) {//常见写法return o1.x-o2.x; //由上面分析,源码,可知,return=1的时候,会交换o1和o2,o1排到o2后面,因此大的对象o1排在小的后面,就是升序return o2.x-o1.x; //反之就是降序}});

Collections.sort简介相关推荐

  1. java list逆序_Java的数组和list升序,降序,逆序函数Collections.sort和Arrays.sort的使用...

    list升序,降序,逆序 Listlist =new ArrayList(); //如果list是 5 7 2 6 8 1 4 1.升序: Collections.sort(list) //list: ...

  2. Java学习打卡第八天——[Collection终结之HashMap,Collections的简介和使用]

    今天已经是学习集合的第三天: [1]第一天学习了Collection集合的List,ArrayList和LinkedList的常用方法和基础规则, ArrayList特点总结: 1.ArrayList ...

  3. java中Collections.sort排序详解

    Comparator是个接口,可重写compare()及equals()这两个方法,用于比价功能:如果是null的话,就是使用元素的默认顺序,如a,b,c,d,e,f,g,就是a,b,c,d,e,f, ...

  4. collections模块简介

    collections模块简介 除python提供的内置数据类型(int.float.str.list.tuple.dict)外,collections模块还提供了其他数据类型,使用如下功能需先导入c ...

  5. Java Collections.sort方法对list集合排序

    1.排序测试类 package com.ljq.test;import java.util.ArrayList; import java.util.Collections; import java.u ...

  6. Collections.sort()的使用

    1.实现Comparable接口(如果List<Object>中Object实现了Comparator接口,便可以直接用以下Collections.sort的方式对List进行排序) pu ...

  7. ht-8 对arrayList中的自定义对象排序( Collections.sort(ListT list, Comparator? super T c))...

    1 package com.iotek.set; 2 3 import java.util.ArrayList; 4 import java.util.Collections; 5 import ja ...

  8. java集合sort底层实现_Java面试总结系列之Collections.sort()

    面试中被问到,集合类中的排序方法是怎么实现的?没有回答上来,故而总结如下:你知道么? 前提:在eclipse中对于自己的代码可以通过按住Ctrl的同时单击名称跳入相应源码中.但eclipse默认没有添 ...

  9. Collections.sort()自定义排序方式

    Java中Collections.sort()的使用! 在日常开发中,很多时候都需要对一些数据进行排序的操作.然而那些数据一般都是放在一个集合中如:Map ,Set ,List 等集合中.他们都提共了 ...

最新文章

  1. 递归和函数栈与setjmp和longjmp的关系
  2. apache+Tomcat均衡负载配置
  3. 练习2.13 不用库函数,写一个高效计算ln N的C函数
  4. 从 Demo 中学习 Solidity
  5. redis desktop manager 连接外网redis服务器
  6. 数字金字塔(信息学奥赛一本通-T1258)
  7. ModalPopupExtender控件主要有两种使用方式:客户端使用方式和服务器端使用方式
  8. 解读clickhouse存算分离在华为云实践
  9. real-time RGB-D camera relocalization
  10. 硬币找零,最长上升子序列,背包问题等动态规划问题详解
  11. 软件测试工程师常见的面试题大全
  12. 【元宇宙系列】元宇宙的创世居民——M 世代(Mateverse)
  13. 三年级计算机之父童年教学设计,三年级语文计算机之父的童年故事课文教学设计...
  14. javascript书籍推荐
  15. error C2059: 语法错误:“常量”解决方案
  16. 【HTML 教程】iframe
  17. 商城系统春节氛围营造
  18. IT服务管理指标体系与报表体系
  19. 百度飞桨AI抠图+图片合成
  20. C语言 递归求n的阶乘和

热门文章

  1. linux在线扩vg命令,lvextend命令 – 扩展逻辑卷空间
  2. Language Modeling(语言模型)
  3. Windows11通过wsl2安装linux图形界面
  4. C++:Assignment to cast is illegal, lvalue casts are not supported
  5. 弘辽科技:对洛丽塔服饰几乎一无所知的圈外人,为什么想开lo店?
  6. 利用信鸽推送提示评论通知
  7. 深度学习面试:用猫和狗的数据做图像分类,分类的效果不好怎么办?
  8. 商品标题的优化操作方法
  9. vue 获取当前div离边框距离_vue获取dom元素的宽高
  10. npm基本使用--npm淘宝镜像设置、常用命令