java 实现Comparable接口和实现Comparator接口排序的区别

news2024/11/15 19:39:13

Comparable接口

  1. 作用
    • Comparable接口是在类的内部实现的,用于指定类的默认比较规则。
    • 当一个类实现了Comparable接口时,它必须实现compareTo方法,该方法用于定义对象之间的自然顺序。
  2. 实现方式
    • 实现Comparable接口的类必须重写compareTo方法,该方法返回一个整数值,表示当前对象与另一个对象的比较结果。
  3. 使用场景
    • 当你需要定义类的默认排序方式时,应该实现Comparable接口。
    • 例如,对于String类,排序时通常使用字典顺序,因此String类实现了Comparable接口。
  4. 举例:
public class Person implements Comparable<Person>{
    private int age;
    private String name;
    Person(int age,String name){
        this.age = age;
        this.name = name;
    }
    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }
    @Override
    public int compareTo(Person o) {
        return this.age-o.age;
    }

    @Override
    public String toString() {
        return name+":"+age;
    }
}

public static void main(String[] args) {
    List<Person> personList = new ArrayList<>();
    personList.add(new Person(15, "zhangsan"));
    personList.add(new Person(12, "lisi"));
    personList.add(new Person(17, "wangwu"));
    System.out.println("排序前");
    System.out.println(personList);
    System.out.println("排序后");
    Collections.sort(personList);
    System.out.println(personList);
}

运行结果
在这里插入图片描述

Comparator接口

  1. 作用
    • Comparator接口是在类的外部实现的,它允许你实现多种不同的排序规则。
    • 通过Comparator,你可以在不修改类本身的情况下,实现多种不同的排序方式。
  2. 实现方式
    • Comparator接口包含一个compare方法,用于比较两个对象的顺序。
    • 通常在创建对象实例时,可以传递一个Comparator对象,用于定义对象的排序方式。
  3. 使用场景
    • 当你需要对某个类的对象进行多种不同的排序时,应该使用Comparator接口。
    • 例如,对于一个Person类,可能需要根据年龄、姓名等字段进行不同的排序,这时就可以创建不同的Comparator实现来实现不同的排序规则。
  4. 举例:
class MyComparator implements Comparator<Person>{
    @Override
    public int compare(Person o1, Person o2) {
        return o2.getAge()-o1.getAge();
    }
}

public static void main(String[] args) {
     List<Person> personList = new ArrayList<>();
     personList.add(new Person(15, "zhangsan"));
     personList.add(new Person(12, "lisi"));
     personList.add(new Person(17, "wangwu"));
     System.out.println("排序前");
     System.out.println(personList);
     System.out.println("排序后");
     //下面可以简写为personList.sort(new MyComparator());
     Collections.sort(personList,new MyComparator());
     System.out.println(personList);
}

运行结果:
在这里插入图片描述

  1. 为了防止误以为是实现Comparable接口才拍的序,这里使用了降序排列

总结:要比较的类实现Comparable接口后只能通过实现的compareTo方法中特定的比较规则进行比较,如果该类有不同的比较需求则没办法满足(例如学生类在A场景下需要按照年龄进行排序,在B场景中需要按照姓名进行排序),Comparator接口不需要比较的类去实现可以根据不同的比较需求自定义不同的比较规则因此更加灵活。

两种方式都实现了,那种的优先级更高?

这取决于Collections.sort()方法是否传入了自定义Comparator排序规则,如果传入了自定义Comparator排序规则那以Comparator为准否则以Comparable为准。

集合可以用Collections.sort()来排序,那数组呢?

对于数组而言可以使用Arrays.sort()来排序,和Collections.sort一样也支持传递自定义排序规则

示例:

Person[] peopleArray = new Person[] { ... }; // 假设这里有一个Person类的数组
Arrays.sort(peopleArray); // 默认按照Person类的compareTo方法(例如按年龄)进行排序
Arrays.sort(peopleArray, new MyComparator()); // 使用自定义的比较器按姓名排序

Set集合如何排序?

Set集合的特点是,无序且元素不能重复,通常情况下是不能直接使用Collections.sort方法来排序的,因为Set接口本身并没有提供排序的保证,如果你希望对Set中的元素进行排序,一般的做法是将Set转换为List,然后再对List进行排序。这样做的好处是可以利用Collections.sort方法来对List进行排序,因为List接口支持有序的元素集合。

示例:

Set<Person> personSet = new HashSet<>(); // 假设这里有一个存放Person类对象的Set集合
personSet.add(new Person(15, "zhangsan"));
personSet.add(new Person(12, "lisi"));
personSet.add(new Person(17, "wangwu"));

// 将Set转换为List
List<Person> personList = new ArrayList<>(personSet);

// 使用Collections.sort对List进行排序
Collections.sort(personList, new MyComparator()); // 使用自定义的比较器按姓名排序

那是所有的Set集合都需要转为List来进行排序吗?有没有特例?

不是所有的Set集合都需要转换为List来排序。在Java中,Set接口的实现类通常有不同的排序保证和特性,具体取决于具体的实现类。下面来介绍常见的Set接口实现类及其排序特性:

  1. HashSet
    • HashSet不保证元素的顺序,因此无法直接使用Collections.sort方法进行排序。如果需要对HashSet中的元素进行排序,首先需要将其转换为List,然后再进行排序。
  2. LinkedHashSet
    • LinkedHashSet保持元素插入的顺序,即元素迭代的顺序与插入顺序一致。可以将LinkedHashSet转换为List,然后利用Collections.sort对List进行排序。
  3. TreeSet
    • TreeSet是按照元素的自然顺序或者通过提供的Comparator进行排序的。因此,如果使用TreeSet存储元素,并且在构造TreeSet时提供了Comparator,那么TreeSet中的元素会按照指定的排序规则进行排序,无需额外的步骤。

示例代码如下所示:

// 使用TreeSet并提供Comparator来存储Person对象
Set<Person> personSet = new TreeSet<>(new MyComparator());
personSet.add(new Person(15, "zhangsan"));
personSet.add(new Person(12, "lisi"));
personSet.add(new Person(17, "wangwu"));

// 因为TreeSet已经按照MyComparator中的排序规则排序,直接打印即可
for (Person person : personSet) {
    System.out.println(person);
}

compare方法返回值说明

  • 返回负数:表示第一个参数应排在第二个参数之前(升序)。
  • 返回零:表示两个参数相等。
  • 返回正数:表示第一个参数应排在第二个参数之后(升序)。

因此,如果你希望实现升序排序,你需要确保在 compare 方法中返回负数或零。如果返回正数,则会导致降序排序。

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

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

相关文章

【Go系列】 Go语言的入门

为什么要学习Go 从今天起&#xff0c;我们将一同启程探索 Go 语言的奥秘。我会用简单明了的方式&#xff0c;逐一讲解 Go 语言的各个知识点&#xff0c;帮助你从基础做起&#xff0c;一步步深化理解。不论你之前是否有过 Go 语言的接触经验&#xff0c;这个系列文章都将助你收获…

农业采摘--RGBD数据转point cloud

一、RGBD图像转点云数据的步骤 将RGBD图像转点云数据常包含五个步骤&#xff1a; 1. 图像采集&#xff1a; 使用RGBD相机同时捕获颜色&#xff08;RGB&#xff09;和深度&#xff08;Depth&#xff09;信息。颜色记录了场景的彩色视觉信息&#xff0c;而深度图像记录了场景中每…

个人面试总结

写在前面&#xff1a;以下是自己在拟录用后回顾总结的了一下当时面试题目&#xff0c;把标答写了出来&#xff0c;供以后复习所使用&#xff0c;希望大家理性食用~~ 预祝大家都能找到心仪的工作 笔试题目&#xff1a; 1.1. java中Collection和Collections的区别 Collection…

Ae After Effects2024 for Mac 视频处理软件

Mac分享吧 文章目录 效果一、准备工作二、开始安装1、Anticc简化版安装1.1双击运行软件&#xff0c;安装1.2 解决来源身份不明的开发者问题1.3 再次运行软件&#xff0c;即可进行AntiCC安装 2. Ae2024安装2.1 打开 Ae 2024 安装包组2.2 将 Ae 安装包拖至桌面2.3 安装 Ae2024 &…

0708,LINUX目录相关操作

主要是冷气太足感冒了&#xff0c;加上少吃药抗药性差&#xff0c;全天昏迷&#xff0c;学傻了学傻了 cat t_chdir.c #include <stdio.h> #include <unistd.h> #include <error.h> #include <errno.h> #include <sys/stat.h>int main(int argc…

PyTorch实现BERT预训练模型转化指南

huggingface官方的介绍&#xff1a; https://huggingface.co/transformers/converting_tensorflow_models.html 直接用命令行 把箭头处路径改为自己放原有tf版本预训练模型的路径 回车后会有一大堆提示&#xff0c;然后发现路径下多了一个bin文件&#xff0c;加上原本的config…

【C++深度学习】多态(概念虚函数抽象类)

✨ 疏影横斜水清浅&#xff0c;暗香浮动月黄昏 &#x1f30f; &#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;C学习 &#x1f680; 欢迎关注&#xff1a;&#x1f44d;点赞 &…

从零开始读RocketMq源码(三)Broker存储Message流程解析

目录 前言 准备 消息载体CommitLog 文件持久化位置 源码解析 broker消息对象MessageExtBrokerInner 异步存储message CommitLog的真相 创建MappedFile文件 加入异步刷盘队列 Message异步存储MappedByteBuffer 总结 前言 在面试中我们经常会听到这样的回答&#x…

31_JQuery一文读懂,JS的升级版

今日内容 零、 复习昨日 一、JQuery 零、 复习昨日 1 js数组的特点(长度,类型,方法) - js数组的长度不限 - 类型不限 - 提供很多方法2 js中和的区别 - 判断数值相等 - 判断数值和数据类型同时相等3 js表单事件的事件名(事件属性单词) - 获得焦点 onfocus - 失去焦点 onblur …

自媒体运营怎样引流客源?

不管是企业还是个人&#xff0c;越来越多都在做自媒体引流运营&#xff0c;那有什么引流客源的方式呢&#xff1f; 高质量内容&#xff1a;创作并分享有价值的内容&#xff0c;吸引目标受众&#xff0c;提升内容的分享和传播效果。 SEO优化&#xff1a;优化文章标题、关键词和…

React学习笔记01

一、学习资料 1.学习网课 黑马程序员前端React18入门到实战视频教程&#xff0c;从reacthooks核心基础到企业级项目开发实战&#xff08;B站评论、极客园项目等&#xff09;及大厂面试全通关_哔哩哔哩_bilibili 2.学习文档 快速入门 – React 中文文档 二、React 1.定义 …

如何在玩客云中安装小雅AList并实现使用手机平板远程连接听歌看电影

文章目录 前言1. 本地部署AList2. AList挂载网盘3. 部署小雅alist3.1 Token获取3.2 部署小雅3.3 挂载小雅alist到AList中 4. Cpolar内网穿透安装5. 创建公网地址6. 配置固定公网地址 前言 本文主要介绍如何在安装了CasaOS的玩客云主机中部署小雅AList&#xff0c;并在AList中挂…

【Vscode】显示多个文件 打开多个文件时实现标签栏多行显示

Vscode显示多个文件&VSCode打开多个文件时实现标签栏多行显示 写在最前面一、解决打开文件的时候只显示一个tab的办法解决办法如下&#xff1a; 二、文件标签栏多行显示设置步骤&#xff1a; &#x1f308;你好呀&#xff01;我是 是Yu欸 &#x1f30c; 2024每日百字篆刻时…

【中项第三版】系统集成项目管理工程师 | 第 11 章 规划过程组① | 11.1 - 11.2

前言 第 11 章对应的内容选择题和案例分析都会进行考查&#xff0c;这一章节属于10大管理的内容&#xff0c;学习要以教材为准。本章上午题分值预计在15分。 目录 11.1 制定项目管理计划 11.1.1 主要输入 11.1.2 主要输出 11.2 规划范围管理 11.2.1 主要输入 11.2.2 主…

比curl更直观的网站性能测试工具httpstat——筑梦之路

GitHub - davecheney/httpstat: Its like curl -v, with colours. wget https://raw.githubusercontent.com/reorx/httpstat/master/httpstat.pymv httpstat.py /usr/bin/httpstat #移动到环境变量路径chmod x /usr/bin/httpstat #添加可执行权限 exec bash #重置当前bash进…

算法训练营day27--122.买卖股票的最佳时机II +55. 跳跃游戏 +45.跳跃游戏 II+1005.K次取反后最大化的数组和

一、 122.买卖股票的最佳时机II 题目链接&#xff1a;https://leetcode.cn/problems/binary-search/description/ 文章讲解&#xff1a;https://www.programmercarl.com/0122.%E4%B9%B0%E5%8D%96%E8%82%A1%E7%A5%A8%E7%9A%84%E6%9C%80%E4%BD%B3%E6%97%B6%E6%9C%BAII.html 视频…

致远漏洞(登陆绕过+任意文件上传)

漏洞复现 1.获得cookie POST /seeyon/thirdpartyController.do HTTP/1.1 Host: 192.168.1.9 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0 Accept: text/html,application/xhtmlxml,application/xml;q0.9,*/*;q0.8 Accept-Langua…

Linux系统之lscpu命令的基本使用

Linux系统之lscpu命令的基本使用 一、lscpu命令介绍二、lscpu命令的使用帮助2.1 命令格式2.2 命令选项2.3 使用帮助 三、lscpu命令的基本使用3.1 查看lscpu版本3.2 直接使用lspcu命令3.3 可解析的格式打印cpu信息3.4 可扩展格式打印cpu信息 四、lscpu命令使用注意事项 一、lscp…

【分布式系统】Ceph块存储系统之RBD接口

目录 一.服务端操作 1.创建一个名为 rbd-xy101 的专门用于 RBD 的存储池 2.将存储池转换为 RBD 模式 3.初始化存储池 4.创建镜像 5.管理镜像 6.Linux客户端使用 6.1.在管理节点创建并授权一个用户可访问指定的 RBD 存储池 6.2.修改RBD镜像特性&#xff0c;CentOS7默认…

【进阶篇-Day7:JAVA中Date、LocalDate等时间API的介绍】

目录 1、概述2、JDK8(-) 时间类2.1 Date类&#xff1a;&#xff08;1&#xff09;构造方法&#xff1a;&#xff08;2&#xff09;常用成员方法&#xff1a; 2.2 SimpleDateFormat类&#xff1a;2.3 总结&#xff1a;2.4 Calendar类介绍&#xff1a; 3、JDK8() 时间类3.1 日历类…