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方法 ...
随机推荐
- Word 设置段前分页
描述 这两个标题在第一个标题的页中,且两个标题都没有独立分页.要让每一个标题独立分页,需要对标题的格式进行修改. 段前分页指的是标题与标题之间不在同一个页中,每一个标题都在独立的页中. 设置段前分页 ...
- LeetCode-1765 地图中的最高点
来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/map-of-highest-peak 题目描述 给你一个大小为 m x n 的整数矩阵 isWa ...
- ImGui引入深度测试的方法
You can use AddCallback() on a given ImDrawList:: to register functions to be run during rendering a ...
- pip 基本问题
pip语法错误 pip换源 更新错误 无模板 Ignoring警告 问题一 (pip语法错误 ) pip list File "<stdin>", line 1 pip ...
- k8s-分布式系统架构master-worker
K8S系列一:概念入门 - 知乎 (zhihu.com) 大白话先了解k8s. k8s是为容器服务而生的一个可移植容器的编排管理工具 概述 Master-Workers 架构(粗译为主从架构)是分布式 ...
- appsettings.json用机密替换字符串-利用 VisualStudio 管理用户机密
以纯文本形式存储密码是不安全的. 例如,存储在中的数据库连接字符串 appsettings.json 可能包含指定用户的 密码: { "ConnectionStrings": { ...
- postman连接mysql数据库
转载:https://www.cnblogs.com/pengxiaojie/p/13495237.html 1.安装 2.启动服务 3.执行sql语句 安装: 想要postman连接mysql,需要 ...
- SAP 采购订单行项目客制化字段增强
需求: 在采购订单行项目中新增客制化字段,区分采购的项目中的物料是量产还是研发物料 开发步骤 主要使用二代增强出口:MM06E005 创建增强项目 事务码T-code:CMOD 创建项目ZEMM001 ...
- u8g2 资料汇集
移植U8g2 https://www.cnblogs.com/frozencandles/p/16358483.html 函数接口说明: https://github.com/olikraus/u8g ...
- vue3 loading 等待效果
一.自定义组件 loading.vue <template> <div class="loading" v-show="msg.show"&g ...