java的排序问题
普通排序
对于基础数据类型的排序,基本只是调用一下方法
如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的排序问题的更多相关文章
- Java 字符排序问题
Java 字符排序问题 未专注于排序算法,而是写了一个MyString类,实现了comparable的接口,然后用Arrays的sort方法来实现排序.我觉得这道题的难度在于如果比较两个.因为大小写的 ...
- java数组排序问题:array.sort()是从小到大排序,那么如何从大到小排序?
别告诉我从i=a.length开始打印然后i--!因为数组没变啊,只是打印顺序变了.有木有啥别的方法,除了冒泡插入选择.. nteger [] array=new Integer[]{1,2,3,4, ...
- java中文排序问题(转)
在Java中,对一个数组或列表(在本文中统称为集合)中的元素排序,是一个很经常的事情.好在Sun公司在Java库中实现了大部分功能.如果集合中的元素实现了Comparable接口,调用以下的静态(st ...
- java代码排序问题
总结: package com.ja; import java.util.Arrays; import java.util.Collections; public class mili { publi ...
- 蓝桥杯-基础练习 :java 数列排序问题
问题描述 给定一个长度为n的数列,将这个数列按从小到大的顺序排列.1<=n<=200 输入格式 第一行为一个整数n. 第二行包含n个整数,为待排序的数,每个整数的绝对值小于10000. 输 ...
- java Map排序问题
java 中,Map常见的有HashMap ,TreeMap等等,Map是一个接口,我们不能直接声明一个Map类型的对象,在实际开发 中,比较常用的Map性数据结构是HashMap和TreeMap,它 ...
- Spark案例分析
一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...
- Java学习-046-日志抓取合并后排序问题解决方案之 --- log4j 二次定制,实现日志输出添加延时10ms
自3月25至今,已经好久没有写学习日志了,今天在写日志抓取合并的小方法,发现抓取后的日志并米有依据系统执行的日志顺序排序.日志抓取排列逻辑如下: 通过日志标识,从各个日志文件(例如 use.log,e ...
- Java中中文拼音的排序问题
最近做一个手机数据同步的应用开发,需要提供地址簿信息按照姓名的拼音次序进行排序.但仔细考察Java提供的Collator之后,发现其中文拼音排序存在严重的问题.Java提供Collator来支持不同语 ...
- java Collection中的排序问题
java Collection中的排序问题 这里讨论list.set.map的排序,包括按照map的value进行排序. 1)list排序 list排序可以直接采用Collections的sort方法 ...
随机推荐
- Git与GitHub的快速使用
Git的快速使用 1. Git简介 Git最初是Linus花了两周时间自己用C写了一个分布式版本控制系统 特点: 分布式,每一个主机都有完整版本库 开源免费性能好 注:类似GitHub这种中心环境的存 ...
- Postgresql之闪回数据库示例
一.摘要 在Oracle中,若发生重大的误操作,那么我们可以使用flashback database命令来把数据库整体闪回到过去的误操作的时间点,当然前提是需要打开数据库的闪回功能. 在PG中,能否也 ...
- Linux操作命令(六)1.wc命令 2.grep命令 3.正则表达式
1.wc 命令是一个统计的工具,主要用来显示文件所包含的行.字和字节数 参数 描述 -c 统计字节数 -l 统计行数 -m 统计字符数,这个标志不能与 -c 标志一起使用 -w 统计字数,一个字被定义 ...
- 将现有vue项目基于electron打包成桌面应用程序 如何隐藏electron窗体的菜单栏
一.前言 项目本来打算采用B/S架构去做的,浏览器网址方式打开还是让用户不方便: 二.使用electron集成桌面应用 本身项目是使用vue-cli开发的,在使用electron之前,需要将本身的项目 ...
- HTML元素关系与CSS初步了解
元素之间的关系 1.父子关系 父子关系就是在一个双标签内嵌套其他元素,那么嵌套在其中的元素就相当于"子",其外层元素相当于"父". <body> ...
- 不用PyScript,网页端运行的Python编辑器
原文:https://lwebapp.com/zh/python-online 需求 有小伙伴可能听说过 PyScript,知道了Python可以通过打包成wasm运行在浏览器端了,这样做一些需要Py ...
- Ubuntu docker安装、验证、卸载
卸载Docker CE 卸载Docker CE软件包: sudo apt-get purge docker-ce 主机上的图像,容器,卷或自定义配置文件不会自动删除.要删除所有图像,容器和卷: sud ...
- transformers 之Trainer对应的数据加载
基础信息说明 本文以Seq2SeqTrainer作为实例,来讨论其模型训练时的数据加载方式 预训练模型:opus-mt-en-zh 数据集:本地数据集 任务:en-zh 机器翻译 数据加载 Train ...
- CS客户端 App.Config更新问题
appconfig更新必须要重启才可以 这个方法为热更新不用重新启动 public void ModifyConfig(string serverName, string dbName, strin ...
- chrome 检查更新时出错:无法启动更新检查(错误代码为 4: 0xA0430817 -- system level)
Windows系统谷歌浏览器 Chrome 检查更新时出错:无法启动更新检查(错误代码为 4: 0x80070005 -- system level)该怎么办? 这很有可能是 Chrome 更新服务被 ...