Java自定义排序用法

Java自定义排序用法

在Java中,我们可以使用自定义排序来对对象或数组进行排序。这可以通过实现 Comparator 接口或使用 Comparable 接口来实现。下面是两种方法的示例:


1.使用 Comparator 接口(常用)

当我们需要以不同的方式比较两个对象时,可以使用 Comparator 接口来实现自定义排序。这个接口有一个方法 compare(T o1, T o2),它接收两个泛型参数 T,并返回一个 int 类型的值。这个返回值指示了两个对象的大小关系,具体含义如下:

  • 如果返回值为负数,则表示 o1 小于 o2——不交换
  • 如果返回值为零,则表示 o1 等于 o2——不交换
  • 如果返回值为正数,则表示 o1 大于 o2——交换

当使用排序算法(如 Arrays.sort()Collections.sort())时,它们会根据 Comparator 的比较结果来决定是否交换两个元素的位置。如果返回值为负数或零,表示元素顺序已经符合要求,不需要交换;如果返回值为正数,表示元素顺序需要交换,算法会进行交换操作。

例如,在以下代码中:

Arrays.sort(array, new Comparator<Integer>() {@Overridepublic int compare(Integer num1, Integer num2) {return num1 - num2;  // 升序排序}
});

如果 compare() 方法返回负数,则表示 num1 小于 num2,这时不会交换它们的位置。如果返回正数,则表示 num1 大于 num2,算法会交换它们的位置。

需要注意的是,如果直接返回 num1 - num2,可能会导致整数溢出问题。为了避免这个问题,可以使用 Integer.compare(num1, num2) 方法,它会考虑到溢出情况,返回正确的比较结果。

Integer.compare(num1, num2) 方法是一个静态方法,用于比较两个整数的大小。它返回一个 int 值。
在排序算法中,当使用 Integer.compare(num1, num2) 方法作为比较器时,根据返回值的不同,交换的情况如下:

  • 如果返回值为负数,则表示 num1 小于 num2,此时不进行交换。
  • 如果返回值为零,则表示 num1 等于 num2,也不进行交换。
  • 如果返回值为正数,则表示 num1 大于 num2,此时会进行交换。

需要注意的是,Integer.compare(num1, num2) 方法会考虑到整数溢出的情况,因此可以安全地使用该方法进行比较。

Arrays.sort(array, new Comparator<Integer>() {@Overridepublic int compare(Integer num1, Integer num2) {return Integer.compare(num1, num2);  // 升序排序}
});

下面是三个不同的例子,用来说明如何使用 Comparator 接口进行自定义排序:

(1) 根据字符串长度排序

在这个例子中,我们将按照字符串长度对字符串数组进行排序。短字符串排在前面,长字符串排在后面。

import java.util.Arrays; // 导入Arrays类,提供了数组相关的工具方法
import java.util.Comparator; // 导入Comparator接口,该接口定义了比较两个对象的方法。public class Main {public static void main(String[] args) {String[] strings = {"aaa", "bb", "c", "dddd"}; // 定义一个字符串数组// 使用Arrays.sort方法对字符串数组进行排序,第二个参数是一个Comparator接口实现类的实例,// 匿名内部类方式实现了Comparator接口,定义比较方法compare,比较规则为比较两个字符串长度大小。Arrays.sort(strings, new Comparator<String>() {@Overridepublic int compare(String s1, String s2) {return s1.length() - s2.length();}});System.out.println(Arrays.toString(strings)); // 打印排序后的字符串数组}
}==========================================================================
import java.util.Arrays;
import java.util.Comparator;public class Main {public static void main(String[] args) {String[] strings = {"aaa", "bb", "c", "dddd"};// 使用Lambda表达式替换匿名内部类实现Comparator接口Arrays.sort(strings, (s1, s2) -> s1.length() - s2.length());System.out.println(Arrays.toString(strings));}
}

在这个例子中,我们使用了匿名内部类来实现 Comparator 接口,并在其中重写了 compare() 方法。
该方法根据字符串的长度进行排序。最后,我们使用 Arrays.sort() 方法对字符串数组进行排序,并输出排序后的结果。


(2) 根据字符串长度和字典序排序

在这个例子中,我们将按照字符串长度和字典序对字符串数组进行排序。短字符串排在前面,长字符串排在后面,如果长度相等,则按照字典序排序。

import java.util.Arrays; // 导入Arrays类,提供了数组相关的工具方法
import java.util.Comparator; // 导入Comparator接口,该接口定义了比较两个对象的方法。public class Main {public static void main(String[] args) {String[] strings = {"aaa", "cc", "bb", "a"}; // 定义一个字符串数组// 使用Arrays.sort方法对字符串数组进行排序,第二个参数是一个Comparator接口实现类的实例,// 匿名内部类方式实现了Comparator接口,定义比较方法compare,比较规则为先比较字符串长度,长度相等时再比较字典序。Arrays.sort(strings, new Comparator<String>() {@Overridepublic int compare(String s1, String s2) {int lenComp = s1.length() - s2.length(); // 比较字符串长度if (lenComp != 0) { // 如果长度不等,则返回长度差值return lenComp;} else { // 如果长度相等,则返回字典序比较结果return s1.compareTo(s2);}}});System.out.println(Arrays.toString(strings)); // 打印排序后的字符串数组}
}
============================================================================
import java.util.Arrays;public class Demo02 {public static void main(String[] args) {String[] strings = { "aaa", "cc", "bb", "a" };// 使用Lambda表达式对字符串数组进行排序Arrays.sort(strings, (s1, s2) -> {int lenComp = s1.length() - s2.length();if (lenComp != 0) {return lenComp;} else {return s1.compareTo(s2);}});System.out.println(Arrays.toString(strings));}
}

在这个例子中,我们同样使用了匿名内部类来实现 Comparator 接口。首先,我们按照字符串的长度进行比较,如果长度相等,则再按照字典序进行比较。最后,我们使用 Arrays.sort() 方法对字符串数组进行排序,并输出排序后的结果。

Tips:

compareTo 是Java中String类的一个方法,用于比较两个字符串的大小关系。

s1.compareTo(s2) 的作用是比较字符串s1和s2的字典序(按照字符的Unicode码值进行比较)。

例如,如果s1是"aaa",s2是"aaab",那么s1.compareTo(s2)将返回一个负数,表示s1在s2之前。

需要注意的是,compareTo方法要求两个字符串必须是非空的,否则可能会抛出空指针异常。因此,在实际使用时,需要确保s1和s2都不为null。


(3)根据对象属性排序

在这个例子中,我们将按照人物的年龄对人物数组进行排序。年龄小的人排在前面,年龄大的人排在后面。

import java.util.Arrays;
import java.util.Comparator;class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public int getAge() {return age;}
}public class Main {public static void main(String[] args) {Person[] people = {new Person("卡卡罗特", 25),new Person("贝吉塔", 20),new Person("龟仙人", 30)};Arrays.sort(people, new Comparator<Person>() {@Overridepublic int compare(Person p1, Person p2) {return p1.getAge() - p2.getAge();}});for (Person person : people) {System.out.println(person.getName() + " - " + person.getAge());}}
}贝吉塔- 20
卡卡罗特 - 25
龟仙人 - 30=============================================================================
public class Demo03 {public static void main(String[] args) {Person[] people = {new Person("Alice", 25),new Person("Bob", 20),new Person("Charlie", 30)};// 使用Lambda表达式替换匿名内部类实现Comparator接口Arrays.sort(people, (p1, p2) -> p1.getAge() - p2.getAge());for (Person person : people) {System.out.println(person.getName() + " - " + person.getAge());}}
}

在这个例子中,我们定义了一个 Person 类,并创建了一个 Person 对象数组。然后,我们使用匿名内部类来实现 Comparator 接口,并在其中重写了 compare() 方法。该方法根据人物的年龄进行比较。最后,我们使用 Arrays.sort() 方法对人物数组进行排序,并输出排序后的结果。

以上就是三个例子,它们展示了如何在 Java 中使用 Comparator 接口进行自定义排序。


2.使用 Comparable 接口

import java.util.Arrays;class Person implements Comparable<Person> {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public int getAge() {return age;}@Overridepublic int compareTo(Person other) {// 按照年龄进行比较return this.age - other.age;}
}public class Demo04 {public static void main(String[] args) {Person[] people = {new Person("Alice", 25),new Person("Bob", 20),new Person("Charlie", 30)};Arrays.sort(people);for (Person person : people) {System.out.println(person.getName() + " - " + person.getAge());}}
}

使用Comparable接口主要适用于单一的比较规则,而Comparator接口对于需要多种或动态比较规则的情况更为常用。


实战例题:(后续更新)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/663182.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Android】高仿京东三级类型列表Demo

本demo基于二级分类双列表联动Demo进行了改进&#xff0c;高仿实现了京东的三级类型列表。 京东的如图&#xff1a; 本demo的&#xff1a; 改进之处 实现了三级列表联动&#xff0c;二三级列表之间的滑动监听优化了一下&#xff0c;将二级类型选中交予自身的点击事件&#…

苏门X学士常识学习

前言 苏轼&#xff08;1037年—1101年&#xff09;是北宋的文坛领袖&#xff0c;很喜欢奖掖后进。其门下最有名的是“苏门四学士”&#xff0c;另外还有“苏门六学士”和“苏门后四学士”之说。 一、苏门四学士 苏轼在《与李昭玘书》中说&#xff1a; 轼蒙庇粗遣&#xff0…

IDEA如何进行远程Debug调试

背景&#xff1a; 使用docker进行CVE漏洞复现的时候&#xff0c;由于只能黑盒进行复现&#xff0c;并不能知道为什么会产生这个漏洞&#xff0c;以及漏洞的POC为什么要这么写&#xff0c;之前我都是通过本地debug来进行源码分析&#xff0c;后来搜了一下&#xff0c;发现可以进…

day36 无重叠区间 划分字母区间 合并区间

题目1&#xff1a;435 无重叠区间 题目链接&#xff1a;435 无重叠区间 题意 intervals[i][starti&#xff0c;endi] 移除区间&#xff0c;使得区间互不重叠&#xff0c;返回移除区间的最小数量 相邻区间挨在一起&#xff0c;尽量移除重叠区间 代码 class Solution { publ…

HCIP-Datacom(H12-821)81-90题解析

有需要完整题库的同学可以私信博主&#xff0c;博主看到会回复将文件发给你&#xff01;&#xff08;麻烦各位同学给博主推文点赞关注和收藏哦&#xff09; 81、在状态检测防火墙中&#xff0c;开启状态检测机制时&#xff0c;三次握手的第二个报文(SYNACK)到达防火墙的时候如…

Qt实现窗口吸附屏幕边缘 自动收缩

先看效果&#xff1a; N年前的QQ就可以吸附到屏幕边缘&#xff0c;聊天时候非常方便&#xff0c;不用点击状态栏图标即可呼出QQ界面 自己尝试做了一个糙版的屏幕吸附效果。 关键代码&#xff1a; void Widget::mouseMoveEvent(QMouseEvent *e) {int dx e->globalX() - l…

户外没有电源和网络,但需要安装监控系统,怎么办?太阳能智能监控系统给你解决

近期有粉丝给小编求助&#xff1a;需要在没网没电的户外进行智能监控的安装&#xff0c;不知道如何解决。收到粉丝的问题&#xff0c;小编立刻联系了技术人员给出方案。针对野外、户外等场景只需使用太阳能供电模组4G摄像机视频监控EasyCVR平台智能分析网关V4的架构&#xff0c…

2024年华为OD机试真题-用连续自然数之和来表达整数-Python-OD统一考试(C卷)

题目描述: 一个整数可以由连续的自然数之和来表示。给定一个整数,计算该整数有几种连续自然数之和的表达式,且打印出每种表达式。 输入描述: 一个目标整数T (1 <=T<= 1000) 输出描述: 该整数的所有表达式和表达式的个数。如果有多种表达式,输出要求为: 1.自然数个…

开始学习第二十七-第二十八天

昨天写的太投入 都忘记了发博客&#xff08;作业对我来说有点多&#xff09; 不过还是学到了不少 然后把扫雷写完啦&#xff01; 下面是代码 game.h 用来定义 #include<stdio.h> #include<time.h> #include<stdlib.h> #define ROW 9 #define COL 9 #def…

《统计学习方法:李航》笔记 从原理到实现(基于python)-- 第5章 决策树

文章目录 第5章 决策树5.1 决策树模型与学习5.1.1 决策树模型5.1.2 决策树与if-then规则5.1.3 决策树与条件概率分布5.1.4 决策树学习5.2 特征选择5.2.1 特征选择问题5.2.2 信息增益5.2.3 信息增益比5.3.1 ID3算法5.3.2 C4.5的生成算法5.4 决策树的剪枝5.5 CART算法5.5.1 CART生…

C++:智能指针

C在用引用取缔掉指针的同时&#xff0c;模板的引入带给了指针新的发挥空间 智能指针简单的来说就是带有不同特性和内存管理的指针模板 unique_ptr 1.不能有多个对象指向一块内存 2.对象释放时内部指针指向地址也随之释放 3.对象内数据只能通过接口更改绑定 4.对象只能接收右值…

20240202在Ubuntu20.04.6下使用whisper.cpp的CPU模式

20240202在Ubuntu20.04.6下使用whisper.cpp的CPU模式 2024/2/2 14:15 rootrootrootroot-X99-Turbo:~/whisper.cpp$ ./main -l zh -osrt -m models/ggml-medium.bin chs.wav 在纯CPU模式下&#xff0c;使用medium中等模型&#xff0c;7分钟的中文视频需要851829.69 ms&#xf…

常见的图形化编程工具都有什么

图形化编程是一种通过可视化界面和模块化组件来进行程序设计的方法&#xff0c;它使得编程更加直观和易于理解&#xff0c;尤其适合初学者和儿童学习编程。在这篇文章中&#xff0c;6547网题库将介绍图形化编程的基本概念、优势以及一些常见的图形化编程工具。 一、图形化编程的…

CAD-autolisp(三)——文件、对话框

目录 一、文件操作1.1 写文件1.2 读文件 二、对话框DCL2.1 初识对话框2.2 常用对话框界面2.2.1 复选框、列表框2.2.2 下拉框2.2.3 文字输入框、单选点框 2.3 Lisp对dcl的驱动2.4 对话框按钮实现拾取2.5 对话框加载图片2.5.1 幻灯片图片制作2.5.1 代码部分 一、文件操作 1.1 写…

密钥加密问题

C参考代码&#xff1a; #include<iostream> #include<map> #include<vector> using namespace std; int main() {vector<char> x;vector<char> y;map<char,char> word;char ch getchar();getchar();string str;getline(cin,str);for(cha…

HashMap的几种遍历方式

entry 增强for循环方式 Map<Integer, String> map new HashMap<>(); map.put(1, "a"); map.put(2, "b"); map.put(3, "c"); map.put(4, "d");Set<Map.Entry<Integer, String>> entrySet map.entrySet();fo…

(科目一)阅读理解

1、题型介绍 1、材料分析题&#xff1a;第三题14分。 2、文章600~1300字左右&#xff0c;篇幅较之前有所增加。 3、题量&#xff1a; 第1问概括&#xff1a;4分。&#xff08;理解文章中的重要概念或句子&#xff09;第2问分析&#xff1a;10分。&#xff08;分析文章中心论…

GmSSL - GmSSL的编译、安装和命令行基本指令

文章目录 Pre下载源代码(zip)编译与安装SM4加密解密SM3摘要SM2签名及验签SM2加密及解密生成SM2根证书rootcakey.pem及CA证书cakey.pem使用CA证书签发签名证书和加密证书将签名证书和ca证书合并为服务端证书certs.pem&#xff0c;并验证查看证书内容&#xff1a; Pre Java - 一…

JDK版本如何在IDEA中切换

JDK版本在IDEA中切换 一、项目结构设置 1.Platform——Settings 项目结构---SDKS 2.Project——SDK 3.Modules——SDK——Sources 4.Modules——SDK——Dependencies 二、设置--编译--字节码版本 Settings——Build,——Java Compiler

【Servlet】——Servlet API 详解

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【Servlet】 本专栏旨在分享学习Servlet的一点学习心得&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 一、HttpServlet二、Htt…