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方法 ...
随机推荐
- K8S 1.20 弃用 Docker 评估之 Docker 和 OCI 镜像格式的差别
背景 2020 年 12 月初,Kubernetes 在其最新的 Changelog 中宣布,自 Kubernetes 1.20 之后将弃用 Docker 作为容器运行时. 弃用 Docker 带来的 ...
- 带你认识3个J.U.C组件扩展
摘要:本文主要为大家讲解3种J.U.C组件扩展. 本文分享自华为云社区<[高并发]J.U.C组件扩展>,作者: 冰 河. 1.FutureTask FutureTask是J.U.C(jav ...
- 运维排查篇 | Linux 连接跟踪表满了怎么处理
nf_conntrack (在老版本的 Linux 内核中叫 ip_conntrack )是一个内核模块,用于跟踪一个网络连接的状态 一旦内核 netfilter 模块 conntrack 相关参数配 ...
- Supported OPs and DPU Limitations
Currently Supported Operators source:https://www.xilinx.com/html_docs/xilinx2019_2/vitis_doc/zmw1606 ...
- 面向对象程序设计第二次blog
一.前言 第四次题目集总结-- 题量:较多 难度:较高 知识点: 获取输入字符串的特定字符类型 获取并储存.计算 循环.选择.字符串.数组的使用 继承 类的设计 总结:题目比较难,题量较少,需要用到正 ...
- Smart200 设计注意设计
2023.02.19 1.固件 2.一套西门子不够,输入输出点数不能满足要求,可配置两套(或多套)smart200,通讯实现一整套功能. 3.中大型PLC项目点数:32.16点位CPU:小型PLC项目 ...
- csp201503-2(数字排序)
问题描述 给定n个整数,请统计出每个整数出现的次数,按出现次数从多到少的顺序输出. 输入格式 输入的第一行包含一个整数n,表示给定数字的个数. 第二行包含n个整数,相邻的整数之间用一个空格分隔,表示所 ...
- 字符类型(char)
字符类型(char) 基本介绍 字符类型可以表示`单个字符`,字符类型是char,char是两个字节(可以存放汉字),多个字符我们用字符串String(我们后面详细讲解String) 案例演示 //演 ...
- oracle 2个数组列,剔除数组重复的数据。
一.下面这样不规则的,数据如何剔除掉.循环筛选replace替换掉. 序号 正常时间 剔除时间 1 2022-12-19,2022-12-20,2022-12-21,2022-12-22,202 ...
- python日志logging配置
python日志logging配置 为了方便ELK收集日志,将日志打印成json格式 开发过程中,使用json格式不方便排查问题 本文章使用python的logging模块,一步步增加配置,来说明每个 ...