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方法 ...
随机推荐
- 记录一个cpu彪高的BUG处理--jvm调优
业务场景:游戏行业,N个服务器,要进行大批量的合服处理,玩家数据会上升,从新整理和服务器的分配情况和逻辑处理,正常开发后,当天白天正常,然后晚上高峰期开始玩家频繁反馈无法登录~~~ 处理逻辑: 优先确 ...
- IIS SSL认证流程& url重写
一.SSL认证 也就是我们常说的服务器认证,为的是启动加密传输协议https,步骤如下: 1.生成证书请求 进入IIS,选择服务器的服务器证书设置选项, 创建证书申请,填值如图所示 选择加密服务提供程 ...
- Spring Boot2中如何优雅地个性化定制Jackson
概述 本文的编写初衷,是想了解一下Spring Boot2中,具体是怎么序列化和反序列化JSR 310日期时间体系的,Spring MVC应用场景有如下两个: 使用@RequestBody来获取JSO ...
- jQuery使用与语法
jQuery安装 1.从官网Download jQuery | jQuery下载安装: 2.CDN在线加载: statistic CDN:https://cdn.staticfile.org/jque ...
- vue学习笔记:vue.js基础语法
一.VUE 概述 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心库只关注视图层,不仅 ...
- 第七周作业-N67044-张铭扬
1. 说明自动化运维的路径,原理,实践方法. 所谓自动化运维是指通过将日常IT运维中大量的重复性工作(小到简单的日常检查.配置变更和软件安装,大到整个变更流程的组织调度)由过去的手工执行转为标准化.流 ...
- C# DevExpress中GridControl控件的基本属性设置和使用方法
1.GridControl隐藏GroupPanel(主面板) 隐藏:鼠标单击Run Designer-OptionsView-ShowGroupPanel=False; 修改:鼠标单击Run Desi ...
- if语法案例
if语法案例 1. 判断系统剩余内存 1) 脚本正文 2) 执行结果 2.监控web和数据库的方法 1) 端口监控 2) 进程监控 3) 客户端模拟 4) 数据库判断* 3.mysql数据库检测命令演 ...
- Spring基本概述
Spring是一个开源框架,官方网站是http://spring.io/,Spring是2003年兴起的一个轻量级的Java开发框架,由lnterface21公司的JavaEE专家RodJohnson ...
- ENGG1310 P2.1 Intro to CE Computer Systems, Programming & Networking
课程内容笔记,自用,不涉及任何 assignment,exam 答案 Notes for self-use, do not include any assignments or exams H/W & ...