java中sort方法的自定义比较器写法

摘要

在做一些算法题时常常会需要对数组、自定义对象、集合进行排序. 在java中对数组排序提供了Arrays.sort()方法,对集合排序提供Collections.sort()方法。对自定义对象排序时要自己重写比较器,对象数组则调用Arrays.sort(),对象集合则调用Collections.sort()。两个方法默认都是升序,也可以重写比较器,实现降序。

对数组排序

sort函数模板, 以int型数组arr为例:

Arrays.sort(arr, new Comparator<Integer>() { // arr是数组名,<>中是待排序集合所包含的数据类型
public int compare(int a, int b){ // 待排序集合中的元素是什么数据类型,这里的两个函数参数就定义为什么数据类型
return a - b; 升序
// return b - a; 降序
// a - b > 0 交换ab位置,反之不变, 即返回值为正数时,交换数组中正在比较的
//两个元素的位置,返回值为负数时,不交换。
}
})
// 注意,要想改变默认的排列顺序,不能使用基本类型(int,double, char)
// 而要使用它们对应的类
Integer[] a2 = { 9, 8, 7, 2, 3, 4, 1, 0, 6, 5 };
Comparator cmp = new MyComparator();
Arrays.sort(a2,cmp);
System.out.println();
for (Integer integer : a2) {
System.out.print(integer+" ");
}
输出:
9 8 7 6 5 4 3 2 1 0
//Comparator是一个接口,所以这里我们自己定义的类MyComparator要implents该接口
// 而不是extends Comparator
class MyComparator implements Comparator<Integer> {
@Override
public int compare(Integer o1, Integer o2) {
// 如果o1小于o2,我们就返回正值,如果o1大于o2我们就返回负值,
// 这样颠倒一下,就可以实现反向排序了
if (o1 < o2) {
return 1;
} else if (o1 > o2) {
return -1;
} else {
return 0;
}
} }

例题: 快速排序

给定你一个长度为n的整数数列。

请你使用快速排序对这个数列按照从小到大进行排序。

并将排好序的数列按顺序输出。

输入格式
输入共两行,第一行包含整数 n。 第二行包含 n 个整数(所有整数均在1~109范围内),表示整个数列。 输出格式
输出共一行,包含 n 个整数,表示排好序的数列。 数据范围
1≤n≤100000
输入样例:
5
3 1 2 4 5
输出样例:
1 2 3 4 5

可以将字符串数组转化为整型数组之后在排序,为了演示自定义比较器的写法这里直接对字符串数组进行排序:

import java.io.*;
import java.util.*; public class Main{
// 输入输出模板
static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out)); static int n;
public static void main(String[] args) throws IOException {
n = Integer.parseInt(in.readLine());
String s[] = in.readLine().split(" ");// 读入数据 Arrays.sort(s, new Comparator<String>() { // 排序
public int compare(String a, String b) {
if(a.length() == b.length()){ // 如果长度相等则直接比较字典序
return a.compareTo(b);
}
else{ // 长度长的一定大
return a.length() - b.length();
}
}
}); for(String p : s){
out.write(p+" ");
} out.flush();
}
}

对集合进行排序

创建TreeSet实例,对其从大到小排序。

因为TreeSet是自动排序和去重的, 默认为升序,我们可以重写比较器构造一个降序的TreeSet, 之后添加数据就会自动排序。

import java.io.*;
import java.util.*; public class Main{
static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out)); public static void main(String[] args) throws IOException { TreeSet<Integer> s = new TreeSet<>(new Comparator<Integer>(){
public int compare(Integer a, Integer b) {
return b - a;
}
}); s.add(10);
s.add(5);
s.add(4);
s.add(6);
s.add(7);
s.add(8);
s.add(1);
s.add(2);
s.add(3);
s.add(9); for(Integer p : s){
out.write(p+" ");
}
out.flush();
}
}
输出:
10 9 8 7 6 5 4 3 2 1

对自定义对象数组排序

创建学生类, 按照年龄从小到大排序

import java.io.*;
import java.util.*; class student{
int age;
String name;
student(int a, String b){
this.age = a;
this.name = b;
}
}
public class Main{
static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out)); public static void main(String[] args) throws IOException {
student s[] = new student[4]; //创建学生对象数组
s[0] = new student(10, "1");
s[1] = new student(9, "2");
s[2] = new student(8, "3");
s[3] = new student(7, "4"); Arrays.sort(s, new Comparator<student>() {
public int compare(student a, student b) { //
return a.age - b.age; // 按照年龄大小升序排列
}
});
for(student p : s){
out.write(p.age+" "+p.name + "\n");
}
out.flush();
}
} 输出:
7 4
8 3
9 2
10 1

大致就是这样了,还可以对要排序的类实现Comparable接口,重写compareTo方法。

代码:

//对pair类实现Comparable接口后,直接调用sort函数排序就行了。
static class pair implements Comparable<pair>{
int a, b, w;
pair(int u, int v, int x){
a = u;
b = v;
w = x;
}
public int compareTo(pair p) {
return this.w - p.w;
}
}

利用 Arrays.sort 字符串 进行排序 完全按字符 排序 忽略字符大小写

有的时候需要对数组里的element进行排序。当然可以自己编写合适的排序方法,但既然java包里有自带的Arrays.sort排序方法,在数组元素比较少的时候为何不用?

Sorting an Array

1. 数字排序
int[] intArray = new int[] {4, 1, 3, -23};
Arrays.sort(intArray);
输出: [-23, 1, 3, 4]
2. 字符串排序,先大写后小写
String[] strArray = new String[] {"z", "a", "C"};
Arrays.sort(strArray);
输出: [C, a, z]
3. 严格按字母表顺序排序,也就是忽略大小写排序 Case-insensitive sort
Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER);
输出: [a, C, z]
4. 反向排序, Reverse-order sort
Arrays.sort(strArray, Collections.reverseOrder());
输出:[z, a, C]
5. 忽略大小写反向排序 Case-insensitive reverse-order sort
Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER);
Collections.reverse(Arrays.asList(strArray));
输出: [z, C, a]

注: 参考 https://blog.csdn.net/weixin_30732825/article/details/98530298

java中sort方法的自定义比较器写法(转载)的更多相关文章

  1. sort方法和自定义比较器的写法

    摘要 在做一些算法题时常常会需要对数组.自定义对象.集合进行排序. 在java中对数组排序提供了Arrays.sort()方法,对集合排序提供Collections.sort()方法.对自定义对象排序 ...

  2. Java中的equals方法和自定义比较器

    Object中的equals()方法默认是按地址比较,而不按内容进行比较, public boolean equals(Object obj) { return (this == obj); } 在S ...

  3. JS高级面试题思路(装箱和拆箱、栈和堆、js中sort()方法、.js中Date对象中的getMounth() 需要注意的、开发中编码和解码使用场景有哪些)

    1.装箱和拆箱: 装箱:把基本数据类型转化为对应的引用数据类型的操作: var num = 123 // num var objNum = new Num(123) // object console ...

  4. java中for循环的6种写法

    有些写法上的说明写的过于武断,可能有很多不当之处,仅供参考.   package ForLoop; import java.util.ArrayList; import java.util.Itera ...

  5. 使用java中replaceAll方法替换字符串中的反斜杠

    今天在项目中使用java中replaceAll方法将字符串中的反斜杠("\")替换成空字符串(""),结果出现如下的异常: java.util.regex.Pa ...

  6. [03]java中的方法以及控制语句

    00 Java中的语句块 语句块(有时叫做复合语句),是用花括号扩起的任意数量的简单Java语句.块确定了局部变量的作用域.块中的程序代码,作为一个整体,是要被一起执行的.块可以被嵌套在另一个块中,但 ...

  7. Java中使用方法的注意事项

    Java方法使用的注意事项 本文列举了几个小白在java中使用方法应该注意的几个地方 1. 方法应该定义在类中2.方法中不可以再嵌套方法3.方法定义的前后顺序无所谓4.想要执行方法必须要调用5.如果方 ...

  8. Java中的方法应用

    一.如何定义java中的方法 所谓方法,就是用来解决一类问题的代码的有序组合,是一个功能模块. 语法: 1. 访问修饰符:方法允许被访问的权限范围, 可以是 public.protected.priv ...

  9. c#和java中的方法覆盖——virtual、override、new

    多态和覆盖 多态是面向对象编程中最为重要的概念之一,而覆盖又是体现多态最重要的方面.对于像c#和java这样的面向对象编程的语言来说,实现了在编译时只检查接口是否具备,而不需关心最终的实现,即最终的实 ...

随机推荐

  1. Mac nasm 汇编入门

    下载 brew install nasm code SECTION .data msg: db "hello world", 0x0a len: equ $-msg SECTION ...

  2. Solon 1.5.11 发布,增加国际化插件

    Solon 是一个轻量的Java基础开发框架.强调,克制 + 简洁 + 开放的原则:力求,更小.更快.更自由的体验.支持:RPC.REST API.MVC.Job.Micro service.WebS ...

  3. ESP32S2获取sht30温湿度

    static const char *TAG = "i2c-temp"; static unsigned char sht30_buf[6]={0}; static float g ...

  4. 2019年最新android常用开源库汇总上篇(转)

    1.基本控件 1.1.TextView ScrollNumber ReadMoreTextView HtmlImage android-autofittextview html-textview Ba ...

  5. Vue数据双向绑定不起作用、Vue如何正确的手动添加json数据、Vue视图层不刷新、手动刷新视图层

    Vue.set(obj,"key","value") 如果接收到来自服务器的消息时,我们需要对其进性进一步处理 我们想当然的会直接将数据添加进json 像这样: ...

  6. IBM刀箱服务器的SW

    刀箱交换机说明: 1.刀箱交换机可以看到的24个口都是ext端口,其中因为授权原因,只激活了前10个端口. 2.交换机配置中的inta端口为服务器直接连接的端口,inta1-inta14,这些都是对应 ...

  7. Python基础4--数据类型

    一.数据类型是什么鬼? 计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各种数值.但是,计算机能处理的远不止数值,还可以处理文本.图形.音频.视频.网页等各种各样的数据,不同 ...

  8. Day12 抽象类、接口、内部类-面向对象编程(3)

    抽象类 abstract修饰符可以用来修饰方法也可以用来修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类: 抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类. ...

  9. Scala学习——模式匹配

    scala模式匹配 1.基础match case(类似java里switch case,但功能强大些) object MatchApp { def main(args: Array[String]): ...

  10. 【Mysql】InnoDB 中的 B+ 树索引

    接上一篇内容,InnoDB 的作者想到一种更灵活的方式来管理所有目录项,是什么? 一.目录项记录页 其实这些用户目录项与用户记录很像,只是目录项中的两个列记录的是主键和页号而已,那么就可以复用之前存储 ...