Java中Collections.sort的使用

作者:Meiko丶 时间:2022-08-20 04:31:49 

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

程序运行结果如下:

Java中Collections.sort的使用

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

程序运行结果如下:

Java中Collections.sort的使用

用sort进行降序排序

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

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

定义一个点类,其中有整型属性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);
   }
   @Override
   public 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);
   }
}

程序结果如下:

Java中Collections.sort的使用

对点进行降序排序

现在对sort方法进行小结:

&emsp;&emsp;实现了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方法的相关源码,我发现其中有这样一段代码:

Java中Collections.sort的使用

sort方法的相关源码

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

Java中Collections.sort的使用

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;
   }
   @Override
   public 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);
   }
}

程序运行结果如下:

Java中Collections.sort的使用

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

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

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

来源:https://blog.csdn.net/u010365819/article/details/120201442

标签:Java,Collections.sort
0
投稿

猜你喜欢

  • springboot框架阿里开源低代码工具LowCodeEngine

    2022-09-01 09:40:41
  • Java调用Oracle存储过程详解

    2022-09-09 03:19:45
  • C#比较时间大小的方法总结

    2023-09-02 04:38:06
  • Spring-Bean创建对象的步骤方式详解

    2023-04-12 22:00:47
  • 详解Spring如何解析占位符

    2023-11-27 12:44:46
  • java抓包后对pcap文件解析示例

    2022-11-23 20:21:53
  • 学习Java内存模型JMM心得

    2023-11-28 20:56:17
  • C# Dockpanel入门基础必看篇

    2023-02-24 18:50:42
  • Spring Boot配置Thymeleaf(gradle)的简单使用

    2023-04-18 07:41:42
  • 详解Java使用JMH进行基准性能测试

    2021-08-01 12:22:32
  • java 生成xml并转为字符串的方法

    2023-01-07 08:27:30
  • SpringBoot LocalDateTime格式转换方案详解(前端入参)

    2022-01-05 06:48:03
  • Java List集合排序实现方法解析

    2023-01-06 05:40:14
  • springboot为异步任务规划自定义线程池的实现

    2022-12-05 01:13:02
  • c# 空合并运算符“??”的使用详解

    2022-11-23 13:47:36
  • Android Studio下载与安装简易教程

    2022-05-28 10:25:30
  • springboot接口参数校验JSR303的实现

    2023-01-19 03:14:56
  • Android开发实现判断通知栏是否打开及前往设置页面的方法

    2022-10-21 10:43:45
  • 利用spring aop实现动态代理

    2022-02-02 16:50:25
  • android 通过向viewpage中添加listview来完成滑动效果(类似于qq滑动界面)

    2023-07-27 19:59:38
  • asp之家 软件编程 m.aspxhome.com