java比较器Comparable接口和Comaprator接口

2023-11-07

java的比较器有两类,分别是Comparable接口和Comparator接口。

在为对象数组进行排序时,比较器的作用非常明显,首先来讲解Comparable接口。

让需要进行排序的对象实现Comparable接口,重写其中的compareTo(T o)方法,在其中定义排序规则,那么就可以直接调用java.util.Arrays.sort()来排序对象数组,实例如下:

View Code
class Student implements Comparable<Student>{
    private String name;
    private int age;
    private float score;
    
    public Student(String name, int age, float score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }
    
    public String toString()
    {
        return name+"\t\t"+age+"\t\t"+score;
    }

    @Override
    public int compareTo(Student o) {
        // TODO Auto-generated method stub
        if(this.score>o.score)//score是private的,为什么能够直接调用,这是因为在Student类内部
            return -1;//由高到底排序
        else if(this.score<o.score)
            return 1;
        else{
            if(this.age>o.age)
                return 1;//由底到高排序
            else if(this.age<o.age)
                return -1;
            else
                return 0;
        }
    }
}

public class ComparableDemo01 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Student stu[]={new Student("zhangsan",20,90.0f),
                new Student("lisi",22,90.0f),
                new Student("wangwu",20,99.0f),
                new Student("sunliu",22,100.0f)};
        java.util.Arrays.sort(stu);
        for(Student s:stu)
        {
            System.out.println(s);
        }
    }
}

程序运行结果:

sunliu 22 100.0
wangwu 20 99.0
zhangsan 20 90.0
lisi 22 90.0

但是在设计类的时候,往往没有考虑到让类实现Comparable接口,那么我们就需要用到另外的一个比较器接口Comparator。

从上面的实例我们可以发现,compareTo(T o)只有一个参数,而Comparator接口中必须要实现的compare(T o1,T o2)就有两个参数。

代码实例:

View Code
package edu.sjtu.ist.comutil;

import java.util.Comparator;

class Student {
    private String name;
    private int age;
    private float score;
    
    public Student(String name, int age, float score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public float getScore() {
        return score;
    }
    public void setScore(float score) {
        this.score = score;
    }

    public String toString()
    {
        return name+"\t\t"+age+"\t\t"+score;
    }

}

class StudentComparator implements Comparator<Student>{

    @Override
    public int compare(Student o1, Student o2) {
        // TODO Auto-generated method stub
        if(o1.getScore()>o2.getScore())
            return -1;
        else if(o1.getScore()<o2.getScore())
            return 1;
        else{
            if(o1.getAge()>o2.getAge())
                return 1;
            else if(o1.getAge()<o2.getAge())
                return -1;
            else 
                return 0;
        }
    }
    
}


public class ComparableDemo02 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Student stu[]={new Student("zhangsan",20,90.0f),
                new Student("lisi",22,90.0f),
                new Student("wangwu",20,99.0f),
                new Student("sunliu",22,100.0f)};
        java.util.Arrays.sort(stu,new StudentComparator());
        for(Student s:stu)
        {
            System.out.println(s);
        }
    }

}

上述程序的运行结果与代码实例1一样。


Comparable与Comparator的区别

Comparable和Comparator都是用来实现集合中元素的比较、排序的。
Comparable是在集合内部定义的方法实现的排序,位于java.util下。
Comparator是在集合外部实现的排序,位于java.lang下。

Comparable是一个对象本身就已经支持自比较所需要实现的接口,如String、Integer自己就实现了Comparable接口,可完成比较大小操作。自定义类要在加入list容器中后能够排序,也可以实现Comparable接口,在用Collections类的sort方法排序时若不指定Comparator,那就以自然顺序排序。所谓自然顺序就是实现Comparable接口设定的排序方式。


Comparator是一个专用的比较器,当这个对象不支持自比较或者自比较函数不能满足要求时,可写一个比较器来完成两个对象之间大小的比较。Comparator体现了一种策略模式(strategy design pattern),就是不改变对象自身,而用一个策略对象(strategy object)来改变它的行为。

总而言之Comparable是自已完成比较,Comparator是外部程序实现比较。


分析二:

再接下来我用小结描述下二者的不同:

1、Comparator在集合(即你要实现比较的类)外进行定义的实现,而Comparable接口则是在你要比较的类内进行方法的实现。这样看来Comparator更像是一个专用的比较器。

2、Comparator实现了算法和数据的分离,从代码也可以看出,其实这和第一点是相辅相成的,因为Comparable依赖于某一个需要比较的类来实现。

3、Comparable支持自比较,自比较是指比如String等类里面本身就有CompareTo()方法,直接就可以进行String类对象的比较,这也可以从较之Comparator,Comparable中Arrays.sort()方法中只带数组参数的形式与书上例子更相似这点看出。 

4、从第3点延伸,我们可以看到当不满足于自比较函数,如String类时,我们试图改写规则要怎么办——通过Comparator因为它支持外比较,它是分离的。

5、当一个又一个类设计完成后,或许我们最初没有设想到类的比较问题,而没使用Comparable接口,那我们之后可以通过Comparator来完成,而同时无需改变之前完成的类的构建。

6、运用Arrays.sort()方法时,注意二者的参数不同,Comparator多了一个参数,这第二个参数是使用Comparator接口的那个被视为专用比较器的类的对象,如汪同学例子中的new ByWeightComparator()。

 

 

其实大部分情况下我们并不需要刻意去对二者做选择,哪个用得顺手就用哪个,但当你的习惯遭遇某种问题时,这样的区别分析可以让你不妨换个方向思考,不至于走入死胡同。

以上分析多是个人理解,如有纰漏,还望加以修正。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java比较器Comparable接口和Comaprator接口 的相关文章

  • 必须掌握的hashcode()方法

    一 hashcode是什么 1 hash和hash表是什么 想要知道这个hashcode 首先得知道hash 通过百度百科看一下 hash是一个函数 该函数中的实现就是一种算法 就是通过一系列的算法来得到一个hash值 这个时候 我们就需要
  • mac上使用IntelliJ IDEA运行项目

    一 Mac OSX系统下安装Tomcat 1 下载Tomcat官方下载地址 2 解压Tomcat到目录 Library 中 并把文件夹名由 apache tomcat 6 0 16 改为 Tomcat 3 打开 应用程序 Applicati
  • java基础:日志框架

    文章目录 一 日志技术的概述 二 日志技术体系 三 Logback日志框架 四 Logback快速入门 五 Logback 配置详解 5 1 输出位置 格式设置 5 2 对日志不同内容是否输出的控制 一 日志技术的概述 程序中的日志可以用来
  • 字符“&”在XML文件中需要被转义

    今天弄Mybatis的配置文件时 因为这样一条语句
  • JAVA: quakus程序运行

    mvnw compile quarkus dev
  • 动力节点老杜java基础视频笔记第一章 学前准备 (1)

    课堂截图 为什么使用截图工具 在听课的过程中 有的时候老师操作的比较快 通过截图的方式将老师的操作保存下来 以便后期的操作 另外截图之后的图片也可以用于笔记的记录 在笔记当中最好采用图文并茂的方式 这样更加利于知识的回顾 使用哪个截图工具
  • 集合addAll方法使用存在的问题。

    集合addAll 方法的时候 这里里有两个集合 集合2要拿到集合1中的元素 然后对集合2进行removeAll方法 结果集合1中的值也没有了 只是因为listTwo listOne 只是把集合1的引用给了集合2 集合1和集合2的引用是指向同
  • FullGC问题分析

    一 常见的FullGC场景分析 频繁的大对象 大对象直接被分配到老年代 系统高负载运行 请求量很大 jvm来不及将对象转移到老年代 直接到老年代分配对象 系统内存泄漏 导致对象长时间在老年代 得不到释放 二 产生FullGC的原因 Syst
  • java数组学习

    2021 2 2 数组 一维数组的使用 1 一维数组的声明和初始化 2 如何调用数组的指定位置的元素 3 如何获取数组的长度 4 如何遍历数组 5 数组元素的默认初始化值 6 数组的内存解析 package day01 import jav
  • Java Json 数据下划线与驼峰格式进行相互转换

    概述 今天遇见一个需求 需要对json数据进行下划线与驼峰格式之间进行转换 在Fastjson Jackson Gson都提供了转换的方式 在这里进行一下列举 User类 public class User private String n
  • Java中变量的作用域【Java基础】

    最近在看 Thinking in Java 想把Java基础再巩固一下 在博客上遇到的以前没注意到的知识点或者较难的知识点记录下来 与大家分享 Java中的基本类型变量的作用域为 int x 1 变量x的作用域只在大括号内 System o
  • javaSE进阶1之static用法

    JavaSE进阶 静态关键字 static static关键字的作用 成员变量分类 静态成员变量 实例成员变量 static修饰成员变量内存原理 static 修饰成员方法的基本用法 成员方法的分类 static修饰成员方法内存原理 sta
  • java 模拟库存管理系统

    本案例要求编写一个程序 模拟库存管理系统 该系统内容主要包括 商品入库 商品显示 和删除商品功能 此程序用手机举例 此管理系统分别为两个类Phone 和Test类 Phone类 确定四个变量 类 1 生成空参数构造方法 2 全部参数的构造方
  • jeecgboot问题解决方案

    常见问题Q A JEECG老版在线文档 点击进入 1 后台访问提示token错误 报错截图 解决方案 JeecgBoot后台的所有请求访问 增加了token机制 所以不能直接访问后台 而需要通过前台登录才能访问 默认前台访问地址 http
  • 求一个数组的最大值最小值及其下标

    求一个数组的最大值最小值及其下标 思路 假定一个数为最大值 如果有个数比假定的最大值还大 那么该数就为最大值 最小值同理 使用for循环 public class MaxMin public static void main String
  • JAVA--GUI(2)--布局

    布局 为了更好适应不同平台而引入的概念 Java的布局管理器是一个实现了LayoutManager接口的实例 用户无法设置setLocation 这些方法 如果想自己设置则需要取消布局管理器 采用布局管理器 边界布局 顺序布局 网格布局 卡
  • SM2加解密、签名验签

    导论 SM2是国家密码管理局于2010年12月17日发布的椭圆曲线公钥密码算法 在我们国家商用密码体系中被用来替换RSA算法 国产SM2算法 是基于ECC的 但二者在签名验签 加密解密过程中或许有些许区别 目前鄙人还不太清楚 后期有机会的话
  • IDEA 编写JDBC 第一个示例

    知心惟有雕梁燕 自来相伴 东风不管琵琶怨 落花吹遍 一 新建一个Module 二 在此Module下新建一个包 在包再建一个包 命名为lib 三 导入mysql驱动 四 将mysql驱动添加到项目的库里 五 代码实现 package Con
  • java基础之HashSet详解

    HashSet详解 HashSet是基于HashMap实现的一个单列存储的集合类 将所有的数据存在HashMap的key值中 而value全部使用一个Object对象存储 继承关系 public class HashSet
  • 详解toLowerCase(判断字符串相等)

    一 toLowerCase 函数简介 toLowerCase 是一个在多个编程语言中都存在的字符串方法 它的作用是将字符串中的所有大写字母转换为对应的小写字母 常用于文本处理 搜索和比较等情况 以确保字符串的一致性和非大小写敏感的操作 二

随机推荐

  • Python 数据分析1:三种工具实现连接、读取MySQL数据库并处理MySQL数据为DataFrame

    文章目录 一 前言 二 通过 pymysql 获取 MySQL 数据 2 1 连接数据库 2 2 读取数据 2 3 处理数据 三 通过 mysqlclient 获取 MySQL 数据 四 通过 SQLAlchemy 获取 MySQL 数据
  • protobuf-IOS简单总结(编译、环境搭建)

    什么是protobuf Protocol Buffers are a way of encoding structured data in an efficient yet extensible format Google uses Pro
  • 用Vue的三种方法实现加减乘除运算

    js插件 vue js 教程 首先在工具内引入vue js 然后在body里面创建一个div并设置id 我这里给id命名为 app div 在id命名为 app 的div内使用input标签和select标签来设置运算框 第一种comput
  • 多个接口请求出现报错,提示会连续出现多个,如何只弹出一个提示

    场景 如果出现网络问题或者token失效 刷新页面 如果有多个接口请求就会出现报错 那么提示就会连续弹出几个 如图 使用的是vue element ui 解决方法 重写一了个message import Message from eleme
  • 爬虫实例九 豆瓣电影详情信息

    from bs4 import BeautifulSoup 网页解析 获取数据 import re 正则提取 import urllib request urllib error 制定url 获取网页数据 import xlwt 进行exc
  • TensorFlow的GPU版本安装

    建议可以使用anaconda创建专门的虚拟环境来安装TensorFlow 因为如果你之后继续在此环境下安装如tensorflow federated 联邦机器学习 的话就会出问题 1 版本准备 注意四个版本是一一对应的 可能改变任何一个的版
  • 程序猿面试必背——Java资料整理

    程序猿面试必背 适用于 Java开发工程师 后台开发工程师 软件开发工程师 写在前面 秋招已结束 以下是对我帮助比较大的资料 分享一下 可能涉及到的知识点 编程语言 Java 基础知识 计算机网络 操作系统 linux 数据库 关系型如my
  • git bash 风格调整

    在用户目录下有一个 C Users minttyrc文件 用文本方式打开文件 将系统配置加入进去即可全局修改git bash的风格 当然也可以在git bash上右击选择options进行修改 个人配置内容如下 参考 Font Consol
  • 创建基于vite的vue项目

    目录 一 环境 安装Node js 安装yarn工具 二 创建项目 三 项目目录梳理 项目初始目录结构 项目加载过程 四 集成UI组件库vant 配置按需加载Vant 使用组件 引入函数组件的样式 五 集成UI组件库NutUI 配置按需加载
  • github 如何

    链接 https www zhihu com question 20393785 answer 105370502 来源 知乎 著作权归作者所有 商业转载请联系作者获得授权 非商业转载请注明出处 原谅我只会用命令行 还是给一个使用命令行的方
  • 详解vant组件应用于Vue2

    目录 1 安装 1 1 npm安装 1 2 CDN安装 1 3 利用脚手架安装 1 3 1 安装脚手架 没有安装脚手架的 1 3 2 利用脚手架创建程序 1 3 3 使用vue ui进行依赖的安装 1 3 4 依赖安装 2 引入组件 2 1
  • express框架的基本使用

    1 引入express const express require express 2 创建应用对象 const app express 3 创建路由规则 request请求报文的封装 response响应报文的封装 app get req
  • C++的float类型数比较问题

    2020 8 17更新了一下 看到了两个float数比较的 不是0值 也加进了最末尾 相等比较 之前刷题做到一道题 看到题解很奇怪 计算一个数字的立方根 getCubeRoot double input 题解采用了二分法 但比较时并不是用直
  • 将多个HEX文件合并成一个HEX文件通过KEIL进行烧录

    首先这多个HEX文件自己已经偏移好了 hex文件已经记录了偏移的地址信息 用记事本打开第一个hex文件 test1 hex 020000040000FA 文件头记录 1000000018F09FE518F09FE518F09FE518F09
  • Docker安装以及运行第一个HelloWorld

    在安装Docker之前我们先来了解一下什么是Docker 观察Docker图标 其实很形象的解释了什么是Docker 在没有使用集装箱的情况下 我们需要考虑不同形状 尺寸的货物怎么安放 货物与货物之间是否能堆叠 这无疑是很繁琐的事情 现在有
  • 005 快排qsort库函数的用法——“C”

    文章目录 前言 一 什么是qsort快排函数 qsort的参数分析 二 使用步骤 前言 Reference C Reference cplusplus com 可在此网站查阅相关函数信息 提示 以下是本篇文章正文内容 下面案例可供参考 一
  • Reachability(判断网络是否连接)

    类似于一个网络状况的探针 NSNotificationCenter defaultCenter addObserver self selector selector reachabilityChanged name kReachabilit
  • 【ROS】学习之日志(log)消息

    参考 ROS学习之日志消息 ROS中的日志 log 消息 ROS日志级别控制 ROS日志 log 系统 通过显示进程的运行状态是好的习惯 但需要确定这样做不会影响到软件的运行效率和输出的清晰度 ROS 日志 log 系统的功能是让程序生成一
  • 傻瓜式阿里云部署java web项目步骤

    写在前面 本傻瓜式步骤适用于阿里云服务器是Windows Server 2008操作系统 一 阿里云操作步骤 1 首先提前准备好阿里云账号和密码 访问地址 阿里云 2 登录后进入首页 点击云服务器ECS 如图 3 进入云服务器ECS 点击实
  • java比较器Comparable接口和Comaprator接口

    java的比较器有两类 分别是Comparable接口和Comparator接口 在为对象数组进行排序时 比较器的作用非常明显 首先来讲解Comparable接口 让需要进行排序的对象实现Comparable接口 重写其中的compareT