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. Tars | Win10下Docker部署TarsJava(SpringBoot)全过程及踩坑记录

    @ 目录 前言 1. 相关环境版本: 坑点一:VMware与Win10 Docker冲突 坑点二:20.版本TarsJava(SpringBoot)依赖文件缺失 2. Docker安装: 坑点三:Do ...

  2. XML:xml常用注解

    @XmlRootelement 指定根目录. //标注在实体类上 @XmlRootElement(name = "xmlEntity") public class XmlEntit ...

  3. Java8 Map中新增的方法使用总结

    前言 得益于 Java 8 的 default 方法特性,Java 8 对 Map 增加了不少实用的默认方法,像 getOrDefault, forEach, replace, replaceAll, ...

  4. Leetcode547 朋友圈解题报告 (DFS

    题目描述: 班上有 N 名学生.其中有些人是朋友,有些则不是.他们的友谊具有是传递性.如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友.所谓的朋友圈,是指所有朋 ...

  5. 谈谈Java事务

    事务具基本特征(ACID) ① Atomi(原子性):事务中包含的操作被看做一个整,要么完全部成功,要么全部失败. ② Consistency(一致性):事务在完成时,必须是所有的数据都保持一致状态, ...

  6. ES异地双活方案

    对于单机房而言,只要参考Elastic Search 官方文档,搭建一个集群即可,示意图如下: 原理类似分布式选举那一套,当一个master节点宕机时,剩下2个投票选出1个新老大,整个集群可以继续服务 ...

  7. git rebase 和 git merger

    & git merge 在上图中,每一个绿框均代表一个commit.除了c1,每一个commit都有一条有向边指向它在当前branch当中的上一个commit. 图中的项目,在c2之后就开了另 ...

  8. 以太网MAC地址组成与交换机基本知识

    以太网MAC地址 MAC地址由48位二进制组成,通常分为六段,用十六进制表示,工作在数据链路层. 数据链路层功能: 链路的建立,维护与拆除 帧包装,帧传输,帧同步 帧的差错恢复 简单的流量控制 第八位 ...

  9. 备战-Java 并发

    备战-Java 并发 谁念西风独自凉,萧萧黄叶闭疏窗 简介:备战-Java 并发. 一.线程的使用 有三种使用线程的方法: 实现 Runnable 接口: 实现 Callable 接口: 继承 Thr ...

  10. tcpdump软件使用

    tcpdump是一个抓包工具, -w 选项是把抓到的包写到二进制文件中,一般扩展名是.cap或.dmp,但tcpdump程序创建文件时并不添加扩展名,可自己指定. -i 是指定要抓包的interfac ...