JAVA中关于compareTo方法的原理深挖

一、compareTo()方法

在深挖compareTo方法前,首先我们需要了解compareTo方法的来龙去脉。compareTo方法的目的是用来比较两个对象的大小的。假如有两个对象a1,a2。包含姓名,年龄,身高三个属性,现在要求根据年龄或者性别进行排序。这就要用到compareTo方法。

二、如何使用compareTo方法

要想使用compareTo方法对对象进行排序,首先要使得该对象类实现comparable接口,并重写compareTo方法,重写compareTo方法时要制定比较规则。

package com.njau.d6_map_impl;import java.util.Objects;public class Student implements Comparable<Student>{private String name;private int age;private double height;public Student(String name, int age, double height) {this.name = name;this.age = age;this.height = height;}@Overridepublic int compareTo(Student o) {return this.age-o.age;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return age == student.age && Double.compare(height, student.height) == 0 && Objects.equals(name, student.name);}@Overridepublic int hashCode() {return Objects.hash(name, age, height);   // 没有重写hashCode之前,不同对象不一样。重写后根据属性计算hash值,属性相同的被认为是同一对象,hash值一样。属性是否一样通过重写的equals方法判断}public Student() {}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 double getHeight() {return height;}public void setHeight(double height) {this.height = height;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", height=" + height +'}';}
}

三、如何指定比较规则

那么该如何指定比较规则呢?这里主要针对int类型数据比较,double类型数据比较以及字符串类型数据比较三种来讲解比较规则:

1.int类型数据比较

int类型的数据指定比较规则最为简单,在重写compareTo方法时,this代表主调对象(主动比较对象),而o代表从调对象(被动比较对象)。Java会默认左边对象是主调对象(this对象),右边对象是从调对象(o对象),这个默认规则是不会改变的。

而比较规则是:当左边对象>右边对象的值时,compareTo方法会返回一个正整数。Java便认为是this对象>o对象(因为Java会默认左边对象就是this,右边对象就是o)。Java排序o,this。

当左边对象<右边对象的值时,compareTo方法会返回一个负整数。Java便认为是this对象<o对象(因为Java会默认左边对象就是this,右边对象就是o)。Java排序this,o。

当左边对象=右边对象的值时,compareTo方法会返回一个负整数。Java便认为是this对象=o对象(因为Java会默认左边对象就是this,右边对象就是o)。

举例说明

package com.njau.d6_map_impl;import java.util.Objects;public class Student implements Comparable<Student>{private String name;private int age;private double height;public Student(String name, int age, double height) {this.name = name;this.age = age;this.height = height;}@Overridepublic int compareTo(Student o) {return this.age-o.age;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return age == student.age && Double.compare(height, student.height) == 0 && Objects.equals(name, student.name);}@Overridepublic int hashCode() {return Objects.hash(name, age, height);   // 没有重写hashCode之前,不同对象不一样。重写后根据属性计算hash值,属性相同的被认为是同一对象,hash值一样。属性是否一样通过重写的equals方法判断}public Student() {}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 double getHeight() {return height;}public void setHeight(double height) {this.height = height;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", height=" + height +'}';}
}

假设this.age>o.age

this.age-o.age。左边this右边o,>0则Java则认为左边对象this>右边对象o,则排序为o,this。升序排序。实际上也是升序排序。 

如果想要降序排序,那么则改为o.age-this.age。左边o右边this,<0则Java则认为左边对象this<右边对象o,则排序为this,o。Java认为是升序排序。实际上是降序排序。

2.double类型数据比较

double类型的数据比较,会出现精度问题,因此不能直接相减。为了解决精度问题,Java中的Double.compare方法派上用场。Double.compare(double1,double2),如果double1>double2,则返回正整数。如果double1<double2,则返回负整数。如果double1=double2,则返回0。这样的话,就符合了Java的比较规则。

return Double.compare(o1.getHeight(),o2.getHeight());

3.字符串类型的数据比较

return this.name.compareTo(o.name);

字符串类型的属性进行比较时,会将字符串转换成字符数组,再通过字符数组进行比较,排序时按照字符的Unicode编码进行排序。首先Java虚拟机会将主调字符串(由编译时生成,也叫做value[])赋给String类中定义的value[]字符数组(使用final定义,只能初始化一次)。

public final class String implements java.io.Serializable, Comparable<String>, CharSequence {// The value is used for character storage.private final char value[];// Other fields and methods...// Constructor to initialize string from character arraypublic String(char value[]) {this.value = Arrays.copyOf(value, value.length);}// Other constructors and methods...
}

紧接着会执行String类中的compareTo方法,将从调字符串进行传入并比较

public int compareTo(String anotherString) {int len1 = this.length();int len2 = anotherString.length();int lim = Math.min(len1, len2);char v1[] = this.value;char v2[] = anotherString.value;int k = 0;while (k < lim) {char c1 = v1[k];char c2 = v2[k];if (c1 != c2) {return c1 - c2;}k++;}return len1 - len2;
}

this:主调字符串

anotherString:从调字符串(在编译阶段会被转换成字符数组)

原理:

获取字符串长度: 

int len1 = this.length();
int len2 = anotherString.length();

length() 方法返回字符串的长度 

将字符串转换为字符数组:

char v1[] = this.toCharArray();
char v2[] = anotherString.toCharArray();

toCharArray() 方法将字符串转换为字符数组。

逐字符比较:

int k = 0;
while (k < lim) {char c1 = v1[k];char c2 = v2[k];if (c1 != c2) {return c1 - c2;}k++;
}

逐字符比较两个字符串,返回第一个不同字符的差值。 

长度比较: 

return len1 - len2;

如果所有字符都相同,则返回字符串长度的差值。

最终会根据Unicode编码比较出字符串的前后顺序。

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

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

相关文章

变长输入神经网络设计

我对使用 PyTorch 可以轻松构建动态神经网络的想法很感兴趣&#xff0c;因此我决定尝试一下。 我脑海中的应用程序具有可变数量的相同类型的输入。对于可变数量的输入&#xff0c;已经使用了循环或递归神经网络。但是&#xff0c;这些结构在给定行的输入之间施加了一些顺序或层…

使用 Conda 管理 Python 环境的详细指南

使用 Conda 管理 Python 环境的详细指南 在安装 Python 时&#xff0c;我们通常会选择 Anaconda 作为管理工具&#xff0c;因为它不仅提供了 Python 的安装包&#xff0c;还集成了许多常用的库和工具&#xff0c;非常适合数据科学和机器学习的工作。Conda 是 Anaconda 中的一个…

Unity3D项目中如何正确使用Lua详解

引言 在Unity3D游戏开发中&#xff0c;Lua作为一种轻量级、灵活且易于学习的脚本语言&#xff0c;被广泛用于游戏逻辑编写、扩展和定制。Lua的集成不仅提高了游戏开发的效率和灵活性&#xff0c;还方便了游戏后期的维护和更新。本文将详细介绍如何在Unity3D项目中正确使用Lua&…

Hugging Face使用笔记

1. HuggingFace简介 Hugging Face Hub和 Github 类似&#xff0c;都是Hub(社区)。Hugging Face可以说的上是机器学习界的Github。Hugging Face为用户提供了以下主要功能&#xff1a; 模型仓库&#xff08;Model Repository&#xff09;&#xff1a;Git仓库可以让你管理代码版…

kei5l中不能跳转到函数定义的原因和个人遇到的问题

快捷键 CTRLK或F12&#xff0c;在选择要查看的函数定义时按下可以查看到&#xff08;文件没问题的情况下&#xff09; 出现不能查看的原因 1&#xff0c;没有设置生成文件信息&#xff08;第一次打开工程常遇到问题&#xff09; 2, 定义函数的代码没有加入工程 解决方式如下…

南大通用数据库-Gbase-8a-学习-44-DDLEVENT恢复

目录 一、环境信息 二、前景提要 1、情况描述 2、3号节点gc_recover日志截图 3、3号节点express日志截图 4、ddlevent截图 5、报错赋权语句分别在1节点和4节点执行 6、gcadmin 三、解决方法 1、描述 2、清理系统user表DDLEVENT 3、拷贝系统user表数据 &#xff08;…

3.js - 灯光与阴影 - 聚光灯

// ts-nocheckimport * as THREE from three // 导入轨道控制器 import { OrbitControls } from three/examples/jsm/controls/OrbitControls // 导入hdr加载器 import { RGBELoader } from three/examples/jsm/loaders/RGBELoader.js // 导入lil.gui import { GUI } from thre…

数据库之索引(三)

目录 一、简述索引实现的原理 二、简述数据库索引的重构过程 三、为什么MySQL的索引使用B树 四、简述联合索引的存储结构及其有效方式 五、MySQL的Hash索引和B树索引有何区别 一、简述索引实现的原理 在MySQL中&#xff0c;索引是在存储引擎层实现的&#xff0c;不同存储引…

ActiViz中的裁剪遮盖vtkImageStencil

文章目录 1. 概念理解2. 核心功能3. 输入与输出4. 参数配置5. 使用场景6. 高级应用与技巧1. 概念理解 vtkImageStencil 是 Visualization Toolkit (VTK) 库中一个至关重要的组件,专为图像处理领域设计,提供了一种高效执行图像掩模操作的机制。在医学成像、遥感技术、计算机视…

SD卡,laptop,启动ubtuntu

你可以按照以下步骤在笔记本电脑上打开SD卡中的Ubuntu系统&#xff1a; 准备工作&#xff1a; 确保你的笔记本电脑有可用的SD卡读卡器接口。如果没有&#xff0c;可以使用外置的USB读卡器。将SD卡插入读卡器中&#xff0c;然后将读卡器插入笔记本电脑的USB接口。 进入BIOS/UEF…

[mac m1]brew升级后icu4c跟着升级,导致启动不了mysql、postgresql

报错信息 /opt/homebrew/opt/postgresql13/bin/postgres Library not loaded: loader_path/../../../../opt/icu4c/lib/libicui18n.73.dylibReferenced from: <596D404A-9AE9-3B57-B2D6-C141A3878204> /opt/homebrew/Cellar/postgresql13/13.12/bin/postgresReason: tr…

软件测试策略:有效应对多环境测试挑战

面对多环境测试的挑战&#xff0c;在软件测试领域&#xff0c;采取一系列策略来确保测试的效率和效果是至关重要的。以下是重新整理并优化后的应对多环境测试的方法&#xff1a; 1. 自动化测试策略 脚本通用化&#xff1a;开发或采用能够在多个环境和平台上运行的自动化测试脚…

【入门篇】2.2 STM32寻址范围(更新中)

写在前面 STM32的寻址范围涉及存储器映射和32位地址线的使用。并且STM32的内存地址访问是按字节编址的,即每个存储单元是1字节(8位)。 一、寻址大小与范围 地址线根数 地址编号(二进制) 地址编号数(即内存大小)

【前端从入门到精通:第十课:移动端布局实战(伸缩盒)】

伸缩盒实战移动端商城 项目参考网址:shopvue.eduwork.cn 目录结构 /bookBrothers/|- index.html 首页|- css/ CSS目录|- base.css 清楚默认样式 设置通用原子类|- bookBrothers.css 全局样式|- index.css index.html文件样式|- img/ 图像资源目录|- font/字体图标目录base.c…

Echarts:渲染成Canvas还是SVG,该如何抉择?

ECharts 从初始一直使用 Canvas 绘制图表。而 ECharts v4.0 发布了 SVG 渲染器&#xff0c;从而提供了一种新的选择。在初始化图表实例时&#xff0c;只需设置 renderer 参数 为 canvas 或 svg 即可指定渲染器&#xff0c;比较方便。贝格前端工场带领大家看下如何选择。 一、C…

如何使用HTML和JavaScript读取文件夹中的所有图片并显示RGB范围

如何使用HTML和JavaScript读取文件夹中的所有图片并显示RGB范围 在这篇博客中&#xff0c;我将介绍如何使用HTML和JavaScript读取文件夹中的所有图片&#xff0c;并显示这些图片以及它们的RGB范围。这个项目使用现代浏览器提供的<input type"file" webkitdirecto…

vue中的12种设计模式

数据存储模式 对于很多状态管理问题来说&#xff0c;最简单的解决方案是使用可组合函数来创建一个可共享的数据存储。 这种模式包含几个部分&#xff1a; 全局状态单例 导出部分或全部状态 用于访问和修改状态的方法 下面是一个简单的例子&#xff1a; 轻量级可组合函数 轻量…

苹果电脑为什么要清理软件?

你有没有想过&#xff0c;你的苹果电脑也许是一个秘密的收藏家&#xff1f;没错&#xff0c;你的Mac可能在悄悄收集那些你曾经用过的每一个字节&#xff0c;从那次偶然下载的应用到你已经忘记了的各种文件。久而久之&#xff0c;这些“收藏品”就会堆积成山&#xff0c;让你的苹…

智能电表在碳中和实现过程中发挥什么作用

智能电表在碳中和实现过程中发挥着至关重要的作用&#xff0c;这些作用主要体现在提高碳排放计量的精准度、推动绿色能源转型、促进电力领域低碳发展等方面&#xff1b;随着技术的不断发展和应用的不断深入相信智能电表将在碳中和实现过程中发挥更加重要的作用。以下是对智能电…

开始尝试从0写一个项目--前端(二)

修改请求路径的位置 将后续以及之前的所有请求全都放在同一个文件夹里面 定义axios全局拦截器 为了后端每次请求都需要向后端传递jwt令牌检验 ps&#xff1a;愁死了&#xff0c;翻阅各种资料&#xff0c;可算是搞定了&#xff0c;哭死~~ src\utils\request.js import axio…