Comparable接口和Comparator接口的使用和区别

2023-11-06

Comparable

Comparable接口在JDK8中的源码:

package java.lang;
import java.util.*;

package java.lang;
public interface Comparable<T> {
    public int compareTo(T o);
}

用法:

public class User implements Comparable<User>{
    private Integer id;
    private Integer age;

    public User() {
    }

    public User(Integer id, Integer age) {
        this.id = id;
        this.age = age;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", age=" + age +
                '}';
    }

    public int compareTo(User o) {
        if(this.age > o.getAge()) {
            return 1;
        }else if(this.age < o.getAge()) {
            return -1;
        }else{
            return 0;
        }
    }
}
public class Test {
    public static void main(String[] args) {
        User user1 = new User(1, 14);
        User user2 = new User(2, 12);
        User user3 = new User(3, 10);
        User[] users = {user1, user2, user3};
        Arrays.sort(users);
        Arrays.stream(users).forEach(System.out::println);
    }
}

int compareTo(T o)

比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。

参数: o - 要比较的对象。

返回:负整数、零或正整数,根据此对象是小于、等于还是大于指定对象。

抛出:ClassCastException - 如果指定对象的类型不允许它与此对象进行比较

Comparator

Comparator接口在JDK8中的源码:

package java.util;

import java.io.Serializable;
import java.util.function.Function;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
import java.util.function.ToDoubleFunction;
import java.util.Comparators;

public interface Comparator<T> {
	int compare(T o1, T o2);
	//还有很多其他方法...
}

使用:

public class Child {
    private Integer id;
    private Integer age;

    public Child() {
    }

    public Child(Integer id, Integer age) {
        this.id = id;
        this.age = age;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Child{" +
                "id=" + id +
                ", age=" + age +
                '}';
    }
}
public class Test {
    public static void main(String[] args) {
        Child child1 = new Child(1, 14);
        Child child2 = new Child(2, 12);
        Child child3 = new Child(3, 10);

        List<Child> list = new ArrayList<>();
        list.add(child1);
        list.add(child2);
        list.add(child3);

        Collections.sort(list, new Comparator<Child>() {
            @Override
            public int compare(Child o1, Child o2) {
                return  o1.getAge() > o2.getAge() ? 1 : (o1.getAge() == o2.getAge() ? 0 : -1);
            }
        });

        // 或者使用JDK8中的Lambda表达式
        //Collections.sort(list, (o1, o2) -> (o1.getAge()-o2.getAge()));

        list.stream().forEach(System.out::println);
    }
}

或者也可以通过实现的方式使用Comparator接口:

import java.util.Comparator;

public class Child implements Comparator<Child> {
    private Integer id;
    private Integer age;

    public Child() {
    }

    public Child(Integer id, Integer age) {
        this.id = id;
        this.age = age;
    }

    @Override
    public int compare(Child o1, Child o2) {
        return o1.getAge() > o2.getAge() ? 1 : (o1.getAge() == o2.getAge() ? 0 : -1);
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Child{" +
                "id=" + id +
                ", age=" + age +
                '}';
    }
}
public class Test {
    public static void main(String[] args) {
        Child child1 = new Child(1, 14);
        Child child2 = new Child(2, 12);
        Child child3 = new Child(3, 10);

        List<Child> list = new ArrayList<>();
        list.add(child1);
        list.add(child2);
        list.add(child3);
        
        Collections.sort(list, new Child());
        list.stream().forEach(System.out::println);
    }
}
Comparator接口其他默认方法的用法

reversed方法

default Comparator<T> reversed() {
        return Collections.reverseOrder(this);
    }

这个方法是用来生成一个逆序器,比如我们开始需要得到一个正序的排序序列,然后又想得到一个反转的排序序列,就可以使用该方法。比如:

public class Test {
    public static void main(String[] args) {
        Child child1 = new Child(1, 14);
        Child child2 = new Child(2, 12);
        Child child3 = new Child(5, 10);
        Child child4 = new Child(4, 10);

        List<Child> list = new ArrayList<>();
        list.add(child1);
        list.add(child2);
        list.add(child3);
        list.add(child4);

        Comparator<Child> comparator = Comparator.comparingInt(x -> x.getAge());
        Collections.sort(list, comparator);
        list.stream().forEach(System.out::println);
        Collections.sort(list, comparator.reversed());
        list.stream().forEach(System.out::println);
    }
}

thenComparing

default <U extends Comparable<? super U>> Comparator<T> thenComparing(
            Function<? super T, ? extends U> keyExtractor)
    {
        return thenComparing(comparing(keyExtractor));
    }

该方法是在原有的比较器上再加入一个比较器,比如先按照年龄排序,年龄相同的在按照id排序。比如:

public class Test {
    public static void main(String[] args) {
        Child child1 = new Child(1, 14);
        Child child2 = new Child(2, 12);
        Child child3 = new Child(5, 10);
        Child child4 = new Child(4, 10);

        List<Child> list = new ArrayList<>();
        list.add(child1);
        list.add(child2);
        list.add(child3);
        list.add(child4);

        Comparator<Child> comparator = Comparator.comparingInt(x -> x.getAge());
        Collections.sort(list, comparator);
        list.stream().forEach(System.out::println);
        System.out.println("-----");
        Collections.sort(list, comparator.thenComparing(x->x.getId()));
        list.stream().forEach(System.out::println);
    }
}

Comparable接口和Comparator接口的区别

  • Comparable接口位于java.lang包下;Comparator位于java.util包下
  • Comparable接口只提供了一个compareTo()方法;Comparator接口不仅提供了compara()方法,还提供了其他默认方法,如reversed()、thenComparing(),使我们可以按照更多的方式进行排序
  • 如果要用Comparable接口,则必须实现这个接口,并重写comparaTo()方法;但是Comparator接口可以在类外部使用,通过将该接口的一个匿名类对象当做参数传递给Collections.sort()方法或者Arrays.sort()方法实现排序。Comparator体现了一种策略模式,即可以不用要把比较方法嵌入到类中,而是可以单独在类外部使用,这样我们就可有不用改变类本身的代码而实现对类对象进行排序。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Comparable接口和Comparator接口的使用和区别 的相关文章

  • 用 @DataJpaTest 注释的测试不是用 @Autowired 注释的自动装配字段

    我有一个 Spring Boot 应用程序 其中包含 Spring Data Jpa 存储库 我需要围绕这个存储库运行单元 或组件 测试 我对 Spring Data Jpa 没有太多经验 这是我的测试 这很简单 我无法让它通过 impor
  • 检查双精度值的等于和不等于条件

    我在比较两者时遇到困难double values using and 我创建了 6 个双变量并尝试进行比较If健康 状况 double a b c d e f if a b c d e f My code here in case of t
  • java.lang.Class: 在 java 程序中初始化 log4j 属性文件时出错

    我正在尝试使用 log4j 运行独立的 java 程序 但在调试时收到以下消息 控制台上没有 log4j 相关日志 log Logger 1343 java lang Class ERROR in 18b4aac2 有人可以建议这里出了什么
  • JTree 节点不会被直观地选择

    不知何故 我无法为我的 JTree 节点启用 选择突出显示 我正在我的项目中使用自定义单元格渲染器 这很可能导致此问题 这是完整的渲染器类代码 protected class ProfessionTreeCellRenderer exten
  • 如何解决 onEditCommit 事件上的类型不匹配错误?

    我在 Fxml 中使用 onEditCommit 事件在用户编辑数据后检索数据 FXML 代码
  • Java替换特定字符

    这是我在这个网站上的第一个问题 所以我会尽量不要成为一个十足的菜鸟 我目前正在用java 创建刽子手游戏 所以我问你的问题是我们是否被赋予了 幽灵 这个词 并将 Ghost 替换为 hiddenWord ghost length for i
  • 为什么我在 Mac 上看到“java.lang.reflect.InaccessibleObjectException: Unable to make private java.nio.DirectByteBuffer(long,int)accessibl

    我已经在工作中愉快地构建代码好几天了 但突然我的一个项目 不是全部 失败并出现此错误消息 看看下面的答案吧 我是如何修复它的 起初我用谷歌搜索 看到很多有这个问题的人正在使用 Java 16 但我认为 错误 我正在使用 Java 11 因为
  • cucumber-junit-platform-engine 中的功能文件发现

    In cucumber junit我使用的库 CucumberOptions定义功能文件位置 package com mycompany cucumber import cucumber api CucumberOptions import
  • 使用 java 按电子邮件发送日历邀请

    我正在尝试使用 java 发送每封电子邮件的日历邀请 收件人收到电子邮件 但不会显示接受或拒绝的邀请 而是将该事件自动添加到他的日历中 我正在使用 ical4j jar 构建活动 邀请 private Calendar getInvite
  • 如何在java中使jpeg无损?

    有没有人可以告诉我如何使用编写 jpeg 文件losslessjava中的压缩 我使用下面的代码读取字节来编辑字节 WritableRaster raster image getRaster DataBufferByte buffer Da
  • jmap - 组织和堆操作会给 jvm 带来开销吗?

    正如标题所述 需要多少开销jmap histo and jmap heap分别带到jvm 如果一个内存敏感的 Java 进程处于OutOfMemory 例如 大约 96 的堆已满 并且无法通过 full gc 清除 其中一项操作是否有可能将
  • 从 Java 日历迁移到 Joda 日期时间

    以前 当我第一次设计股票应用相关软件时 我决定使用java util Date表示股票的日期 时间信息 后来我体会到了大部分方法java util Date已弃用 因此 很快 我重构了所有代码以利用java util Calendar 然而
  • 让JScrollPane控制多个组件

    对于我的应用程序 我正在设计一个脚本编辑器 目前我有一个JPanel其中包含另一个JPanel保存行号 位于左侧 以及JTextArea用于允许用户输入代码 位于右侧 目前 我已经实施了JScrollPane on the JTextAre
  • OpenJDK 版本控制

    上下文 我想确保我们系统上安装的 Java 不受 CVE 2022 21449 的影响 java version 给出 openjdk version 11 0 7 2020 04 14 LTS OpenJDK Runtime Enviro
  • 如何为 Jackson 编写一个包罗万象的(反)序列化器

    当您提前知道类型时 编写自定义序列化器非常容易 例如 MyType一个人可以写一个MyTypeSerializer extends StdSerializer
  • 从 Stax XMLStreamReader 读取以解组部分

    我正在使用 Stax 游标 API 从大型 xml 文件中提取数据 当前 我转到特殊标签的开头并使用 JAXB 解组该标签 这对于格式良好的 xml 文件效果很好 但不久前我有一个文档 其中数十万个标签中有一个未关闭 JAXB 使用 XML
  • 来自客户端的超时 Web 服务调用

    我正在使用 RestEasy 客户端调用网络服务 一项要求是 如果调用运行时间超过 5 秒 则中止 超时调用 我如何使用 RestEasy 客户端实现这一目标 我只看到服务器端超时 即如果在一定时间内未完成请求 Rest Easy 网络服务
  • 我想要一个 Java 阿拉伯语词干分析器

    我正在寻找阿拉伯语的 Java 词干分析器 我找到了一个名为 AraMorph 的库 但它的输出是无法控制的 并且它会形成不需要的单词 还有其他阿拉伯语词干分析器吗 这是新的阿拉伯语词干分析器 Assem 的阿拉伯语轻词干分析器 http
  • 从一个文本文件中获取数据并将其移动到新的文本文件

    我有一个文件 里面有数据 在我的主要方法中 我读入文件并关闭文件 我调用另一种方法 在原始文件的同一文件夹内创建一个新文件 所以现在我有两个文件 原始文件和通过我调用的方法生成的文件 我需要另一种方法 从原始文件中获取数据并将其写入创建的新
  • 如何将实例变量传递到 Quartz 作业中?

    我想知道如何在 Quartz 中外部传递实例变量 下面是我想写的伪代码 如何将 externalInstance 传递到此作业中 public class SimpleJob implements Job Override public v

随机推荐

  • oracle生成标准uuid,Oracle 生成uuid方法

    近日 遇到朋友问及如何生成UUID 是 通用唯一识别码 Universally Unique Identifier 方法 其实数据中是支持的 Oracle中生成跨系统的唯一识别符UUID非常方便 比生成序列还简单 直接用sys guid 就
  • Stable Doodle:简单涂鸦一键变成艺术品

    摘要 Stable Doodle 是一款使用 AI 技术将简单涂鸦转化为艺术品的应用 它可以帮助用户快速 轻松地创作出精美的图画 本教程将介绍 Stable Doodle 的基本使用方法 正文 Stable Doodle 的使用非常简单 只
  • 2080ti,驱动安装,CUDA安装,CUDNN安装,CUDA10.1的不兼容问题

    发现问题 哎呦 我跑的是CPU 不是GPU 解决问题 Tensorflow目前不支持CUDA10 1 继续解决问题 哎呦 驱动被不小心删掉了 那就全部重新安装吧 最终解决好了 跑起来了 看似GPU 其实跑的是CPU 之前写了代码发现 能跑起
  • 分布式版本控制VS集中式版本控制

    集中式版本控制 诸如CVS SVN等 都有一个集中管理的服务器 保存所有的文件修订版本 而协同工作的人们都通过客户端连接到这台服务器 取出最新的文件或者提交更新 如上图所示 A B C为三位开发者 这是A将代码拉到本地进行开发 这个时候A开
  • raise_for_status()方法

    raise for status 方法 理解Response类非常重要 Response这样的一个对象返回了所有的网页内容 那么它也提供了一个方法 叫raise for status 这个方法是专门与异常打交道的方法 该方法有这样一个有趣的
  • 如何模拟弱网条件 - 限流, 丢包, 延迟和抖动

    Abstract 弱网条件的模拟 Authors Walter Fan Category learning note Status v1 0 Updated 2023 02 16 License CC BY NC ND 4 0 概述 在网络
  • 什么是车联网

    要弄清车联网是什么 还要从许多年前说起 比尔 盖茨等人曾提出物联网的概念 即 万物相连的互联网 物联网是要将各种信息传感设备与互联网结合起来从而形成一个的巨大的网络 简单来说 就是给各种各样的事物连上互联网 然后人们可以通过某个设备远程监控
  • 如何高效定位网络丢包问题?

    引言 本期分享一个比较常见的网络问题 丢包 例如我们去ping一个网站 如果能ping通 且网站返回信息全面 则说明与网站服务器的通信是畅通的 如果ping不通 或者网站返回的信息不全等 则很可能是数据被丢包了 类似情况想必大家都不陌生 针
  • java后端使用websocket实现与客户端之间接收及发送消息

    客户端请求websocket接口 连接通道 我这边业务成功客户端发消息 客户端自动刷新 接口 ws localhost 8080 websocket xx import org springframework web socket conf
  • Docker 安装 ES eslasticsearch

    Docker 安装 ES eslasticsearch 1 下载镜像 我这里下载的是 6 8 14 如果你不知道有哪些版本 可以查看 https hub docker com elasticsearch root localhost jzj
  • Java线程池多线程查询数据库提高查询效率

    Java线程池多线程查询数据库提高查询效率 需求 问题 思路 代码 解析 需求 公司数据统计报表查询 几张大表关联查询 包含跨库查询 数据联查 数据过滤 数据统计 问题 主表数据1 主表数据2 统计数据1 统计数据2 数据 数据 数据 数据
  • Linux_centos安装后无法进入图形界面

    问题 直接默认进入字符界面 root之后init 5也没用 解决方法 出现问题的原因在于安装时选择了最小安装 如图所示 转载于 https www cnblogs com vocoub p 11537978 html
  • OpenHarmony 3.1Release 电话功能演示—基于润和DAYU200开发套件

    1 前言 令人期待的OpenHarmony 3 1Release终于在3月31号发布了 目前DAYU200是首款支持OpenHarmony 3 1 Release版本的开发套件 官方购买链接购买 淘宝 https item taobao c
  • mac安装lrzsz出错Command failed with exit 128: git

    终端检查电脑是否安装了rz和sz which sz 若报错 则需要下载 由于网络和代理的原因 以下命令会报错 brew install lrzsz 是因为brew和git配置的代理存在冲突 对于无外网链接功能 无特殊配置的git而言 需要安
  • spring的注入bean的几种方式

    平常的Java开发中 程序员在某个类中需要依赖其它类的方法 通常是new一个依赖类再调用类实例的方法 这种开发存在的问题是new的类实例不好统一管理 Spring提出了依赖注入的思想 即依赖类不由程序员实例化 而是通过Spring容器帮我们
  • Linux命令行模式和图形界面的切换

    1 1 命令行 gt 图形 执行startx命令 1 2 图形 gt 命令行 Ctrl Alt F1 F6 2 启动默认 系统开机进入的界面 2 1 启动进入命令行模式 修改 etc inittab文件 id 3 initdefault 2
  • ERROR Error: No module factory availabl at Object.PROJECT_CONFIG_JSON_NOT_VALID_OR_NOT_EXIST ‘Error

    1 使用微信一键打包工具提示 ERROR Error No module factory available for dependency type CssDependency Error 请检查 project config json 是
  • 在运行jar包时如何替换jar内变量的值?

    在运行jar包时如何替换jar内变量的值 举个例子 1 问题描述 java程序中定义了变量String vars System getProperty aa String vars1 System getProperty aa test 把
  • 【计算机知识】Base64 编码说明

    一 理论 Base64 是一种基于 64 个可打印字符来表示二进制数据的表示方法 由于 2 6 64 所以每 6 个比特为一个单元 对应某个可打印字符 Base64 常用于在通常处理文本数据的场合 表示 传输 存储一些二进制数据 包括 MI
  • Comparable接口和Comparator接口的使用和区别

    Comparable Comparable接口在JDK8中的源码 package java lang import java util package java lang public interface Comparable