普通排序

对于基础数据类型的排序,基本只是调用一下方法

如java的

1 Arrays.sort(nums);

那么如何自定义排序规则呢?

自定义排序规则:

假设现在有这么个问题,有n个学生, 每个学生有一个数学成绩,有一个语文成绩,

要求按照总分从高到低排序,分数一样,再按照数学成绩从低到高, 再一样则按照语文成绩从高到低。

这个问题该怎么解决呢?

对于java, 我们有两种方式,一种是自定义Comparator比较器, 另一种是类实现Comparable接口。

首先我们定义一个学生类:

 1 class Student {
2 int math; // 数学成绩
3 int chinese; // 语文成绩
4 public Student(int math, int chinese) {
5 this.math = math;
6 this.chinese = chinese;
7 }
8
9 // 返回总成绩
10 public int sum() {
11 return this.math + this.chinese;
12 }
13 }

Comparator比较器:

自定义一个比较对象:

 1     public static Comparator<Student> cmp = new Comparator<Student>(){
2
3 @Override
4 public int compare(Student o1, Student o2) {
5 if (o1.sum() == o2.sum()) {
6 if (o1.math == o2.math) {
7 return Integer.compare(o1.chinese, o2.chinese);
8 } else {
9 // 按数学成绩从低到高,如果需要反过来,则把1和-1换个位置
10 return o1.math > o2.math ? 1 : -1;
11 }
12 } else {
13 // 按总分从高到低,如果需要从低到高,则把1和-1换个位置
14 return o1.sum() < o2.sum() ? 1 : -1;
15 }
16 }
17 };

这个比较器接口中, 有一个compare方法, 方法返回0, 1, -1 三个值, 0代表相等, -1代表o1小于o2, 1代码o1大于o2。

根据我们的比较规则,在compare方法中返回对应的值。

有了这个比较器,那么就可以进行排序:

1 Arrays.sort(students, cmp); // students是学生对象数组,cmp是我们的比较器

当然,如果这个比较器只需要用一次,也可以用匿名内部类的方式,如下:

 1         Arrays.sort(students, new Comparator<Student>() {
2 @Override
3 public int compare(Student o1, Student o2) {
4 if (o1.sum() == o2.sum()) {
5 if (o1.math == o2.math) {
6 return Integer.compare(o1.chinese, o2.chinese);
7 } else {
8 // 按数学成绩从低到高,如果需要反过来,则把1和-1换个位置
9 return o1.math > o2.math ? 1 : -1;
10 }
11 } else {
12 // 按总分从高到低,如果需要从低到高,则把1和-1换个位置
13 return o1.sum() < o2.sum() ? 1 : -1;
14 }
15 }
16 });

完整代码如下:

 1 import java.util.Arrays;
2 import java.util.Comparator;
3 import java.util.Scanner;
4
5 class Student {
6 int math; // 数学成绩
7 int chinese; // 语文成绩
8 public Student(int math, int chinese) {
9 this.math = math;
10 this.chinese = chinese;
11 }
12
13 // 返回总成绩
14 public int sum() {
15 return this.math + this.chinese;
16 }
17 }
18
19 public class Main {
20 public static void main(String[] args) {
21 Scanner in = new Scanner(System.in);
22 int n = in.nextInt();
23 Student[] students = new Student[n];
24 for (int i=0; i<n; i++) {
25 students[i] = new Student(in.nextInt(), in.nextInt());
26 }
27 Arrays.sort(students, new Comparator<Student>() {
28 @Override
29 public int compare(Student o1, Student o2) {
30 if (o1.sum() == o2.sum()) {
31 if (o1.math == o2.math) {
32 return Integer.compare(o1.chinese, o2.chinese);
33 } else {
34 // 按数学成绩从低到高,如果需要反过来,则把1和-1换个位置
35 return o1.math > o2.math ? 1 : -1;
36 }
37 } else {
38 // 按总分从高到低,如果需要从低到高,则把1和-1换个位置
39 return o1.sum() < o2.sum() ? 1 : -1;
40 }
41 }
42 });
43 for(int i=0; i<n; i++) {
44 System.out.printf("%d %d\n", students[i].math, students[i].chinese);
45 }
46 }
47 }

第二种方式: 类实现Comparable接口

这种方式是在学生类中实现Comparable接口, 这样这个类的对象就可以进行比较了, 从而不需要在sort方法中传比较器

以下是Student类的实现:

 1 class Student implements Comparable{
2 int math; // 数学成绩
3 int chinese; // 语文成绩
4 public Student(int math, int chinese) {
5 this.math = math;
6 this.chinese = chinese;
7 }
8
9 // 返回总成绩
10 public int sum() {
11 return this.math + this.chinese;
12 }
13
14 @Override
15 public int compareTo(Object o) {
16 Student other = (Student) o; // 先对o进行转型为Student对象
17 if (this.sum() == other.sum()) {
18 if (this.math == other.math) {
19 return Integer.compare(this.chinese, other.chinese);
20 } else {
21 // 按数学成绩从低到高,如果需要反过来,则把1和-1换个位置
22 return this.math > other.math ? 1 : -1;
23 }
24 } else {
25 // 按总分从高到低,如果需要从低到高,则把1和-1换个位置
26 return this.sum() < other.sum() ? 1 : -1;
27 }
28 }
29 }

接下来排序,就和基本数据类型排序一样了, 不需要传入比较器。

Arrays.sort(students);

完整代码如下:

 1 import java.util.Arrays;
2 import java.util.Comparator;
3 import java.util.Scanner;
4
5 class Student implements Comparable{
6 int math; // 数学成绩
7 int chinese; // 语文成绩
8 public Student(int math, int chinese) {
9 this.math = math;
10 this.chinese = chinese;
11 }
12
13 // 返回总成绩
14 public int sum() {
15 return this.math + this.chinese;
16 }
17
18 @Override
19 public int compareTo(Object o) {
20 Student other = (Student) o; // 先对o进行转型为Student对象
21 if (this.sum() == other.sum()) {
22 if (this.math == other.math) {
23 return Integer.compare(this.chinese, other.chinese);
24 } else {
25 // 按数学成绩从低到高,如果需要反过来,则把1和-1换个位置
26 return this.math > other.math ? 1 : -1;
27 }
28 } else {
29 // 按总分从高到低,如果需要从低到高,则把1和-1换个位置
30 return this.sum() < other.sum() ? 1 : -1;
31 }
32 }
33 }
34
35 public class Main {
36 public static void main(String[] args) {
37 Scanner in = new Scanner(System.in);
38 int n = in.nextInt();
39 Student[] students = new Student[n];
40 for (int i=0; i<n; i++) {
41 students[i] = new Student(in.nextInt(), in.nextInt());
42 }
43 Arrays.sort(students);
44 for(int i=0; i<n; i++) {
45 System.out.printf("%d %d\n", students[i].math, students[i].chinese);
46 }
47 }
48 }

总结:

1. Java里面数组排序是用Arrays.sort 方法

2. 对于基本数据类型可以直接使用进行排序, 但遵循的是默认的大小比较。

3. 如果要自定义排序规则, 或者对对象数组进行排序, 则可以有两种方式

4. 单独定义一个比较器对象Comparator,将排序规则写在compare方法中, 调用sort方法时,传入这个比较器

5. 对于类,可以实现Comparable接口,重写compareTo方法, 这样这个类对象的数组进行排序时,不需要传入比较器,会用类中实现的CompareTo方法进行比较,从而排序。

6. 如果一个类实现了Comparable接口, 同时排序时又传入了一个比较器, 那么优先使用传入的比较器进行排序。

比如我们的Integer等类,都是实现了Comparable接口的, 但你想用自己的规则排序,还是可以创建一个Comparator比较器,排序时传入sort方法中

 

java的排序问题的更多相关文章

  1. Java 字符排序问题

    Java 字符排序问题 未专注于排序算法,而是写了一个MyString类,实现了comparable的接口,然后用Arrays的sort方法来实现排序.我觉得这道题的难度在于如果比较两个.因为大小写的 ...

  2. java数组排序问题:array.sort()是从小到大排序,那么如何从大到小排序?

    别告诉我从i=a.length开始打印然后i--!因为数组没变啊,只是打印顺序变了.有木有啥别的方法,除了冒泡插入选择.. nteger [] array=new Integer[]{1,2,3,4, ...

  3. java中文排序问题(转)

    在Java中,对一个数组或列表(在本文中统称为集合)中的元素排序,是一个很经常的事情.好在Sun公司在Java库中实现了大部分功能.如果集合中的元素实现了Comparable接口,调用以下的静态(st ...

  4. java代码排序问题

    总结: package com.ja; import java.util.Arrays; import java.util.Collections; public class mili { publi ...

  5. 蓝桥杯-基础练习 :java 数列排序问题

    问题描述 给定一个长度为n的数列,将这个数列按从小到大的顺序排列.1<=n<=200 输入格式 第一行为一个整数n. 第二行包含n个整数,为待排序的数,每个整数的绝对值小于10000. 输 ...

  6. java Map排序问题

    java 中,Map常见的有HashMap ,TreeMap等等,Map是一个接口,我们不能直接声明一个Map类型的对象,在实际开发 中,比较常用的Map性数据结构是HashMap和TreeMap,它 ...

  7. Spark案例分析

    一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...

  8. Java学习-046-日志抓取合并后排序问题解决方案之 --- log4j 二次定制,实现日志输出添加延时10ms

    自3月25至今,已经好久没有写学习日志了,今天在写日志抓取合并的小方法,发现抓取后的日志并米有依据系统执行的日志顺序排序.日志抓取排列逻辑如下: 通过日志标识,从各个日志文件(例如 use.log,e ...

  9. Java中中文拼音的排序问题

    最近做一个手机数据同步的应用开发,需要提供地址簿信息按照姓名的拼音次序进行排序.但仔细考察Java提供的Collator之后,发现其中文拼音排序存在严重的问题.Java提供Collator来支持不同语 ...

  10. java Collection中的排序问题

    java Collection中的排序问题 这里讨论list.set.map的排序,包括按照map的value进行排序. 1)list排序 list排序可以直接采用Collections的sort方法 ...

随机推荐

  1. PostgreSQL数据库所有的等待事件

    Wait Event Type Wait Event Name Description LWLock ShmemIndexLock Waiting to find or allocate space ...

  2. Reverse for 'blog_detail.html' not found.解决方法

    初学django遇到了以下问题: 查找解决方法的时候发现有以下几个原因: 1.字母打错 2.多加了空格 随后 我发现 报错的代码中多加了'.html'..删掉后就没问题了.

  3. web实践学习3

    web实践学习3 20201303张奕博 2023.1.26 创建树 从预览动图和页面可以看到,浮岛上共有两种树 ,绿色的高树和粉红色的矮树,树的实现也非常简单,是使用了两个 BoxBufferGeo ...

  4. 四大组件之服务Service

    参考:Android开发基础之服务Service 什么是服务呢? 用俗话话应该是长期于后台运行的程序,如果是官方一点,首先它是一个组件,用于执行长期运行的任务,并且与用户没有交互. 每一个服务都需要在 ...

  5. conda创建和启动python虚拟环境

    conda与python虚拟环境 创建环境 conda create -n ENV_NAME python=3.9 激活环境 conda activate ENV_NAME 给虚拟环境安装包: con ...

  6. gitlab 搭建代理踩坑

    公司的外网服务被黑客攻击,所以需要重置服务器 -- 此为前提 gitlab 的安装 网上找吧. 迁移前置条件 1. 迁移备份 gitlab 时,需要确保双方服务器的gitlab 版本相同 cat /o ...

  7. java 注解基础

    java 内置注解 注解 作用 描述 @Override 将覆盖父类中的方法 作用在子类的方法上 @Deprecated 代码被弃用 使用了被@Deprecated注解的代码则编译器将发出警告 @Su ...

  8. deepinlinux安装golang

    Download 从 Google 官方获取安装包,不用FQ直接访问 http://golang.google.cn,选择 Linux 的安装包如 go1.14.linux-amd64.tar.gz ...

  9. 【C++】【纯代码】获取电脑的mac地址

    bool GetMacAddress(CString &LanMAC) { #define MAX_ADAPTER_NAME_LENGTH 256 #define MAX_ADAPTER_DE ...

  10. Vue I18n Vue.js 的国际化插件+elementUI的使用

    先附上插件官网 vue-i18n中文官网 我们的vue项目需要支持多语言时,可以使用这个插件 安装插件教程在官网可以找到 代码结构可以如下 zh.js 查看代码 export default { lo ...