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;
}
@Override
public int compareTo(Student o) {
return this.age-o.age;
}
@Override
public 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);
}
@Override
public 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;
}
@Override
public 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;
}
@Override
public int compareTo(Student o) {
return this.age-o.age;
}
@Override
public 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);
}
@Override
public 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;
}
@Override
public 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 array
public 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编码比较出字符串的前后顺序。
到此这篇关于JAVA中compareTo方法的使用小结的文章就介绍到这了,更多相关JAVA compareTo内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
- Java中compareTo方法使用小结
- Java中BigDecimal的equals方法和compareTo方法的区别详析
- Java中BigDecimal比较大小的3种方法(compareTo()、equals()和compareTo())
- Java compareTo用法详解
- JavaSE中compare、compareTo的区别
- Java 基础:string中的compareTo方法
- java compare compareTo方法区别详解
- java compareTo和compare方法比较详解
- java使用compareTo实现一个类的对象之间比较大小操作
- Java中替代equals,compareTo和toString的方法
- Java中比较运算符compareTo()、equals()与==的区别及应用总结
- 详解java中保持compareTo和equals同步
相关文章
基于spring-boot-maven-plugin插件打包lib文件外置的方法(layout模式为ZIP模式)
Maven是一个插件执行框架,所有工作都由插件完成,同时 Maven 基于构建生命周期的核心概念,明确定义了构建和分发特定工件(项目)的过程,接下来通过本文给大家介绍下基于spring-boot-maven-plugin插件打包lib文件外置(layout模式为ZIP模式),需要的朋友可以参考下2022-09-09
springboot+maven多环境动态配置及编译失败的解决方案(步骤详解)
这篇文章主要介绍了springboot+maven多环境动态配置及编译失败的解决方案,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧2023-11-11
maven package 打包报错 Failed to execute goal的解决
这篇文章主要介绍了maven package 打包报错 Failed to execute goal的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2020-11-11
透彻理解Java中Synchronized(对象锁)和Static Synchronized(类锁)的区别
这篇文章主要介绍了Java中Synchronized(对象锁)和Static Synchronized(类锁)的区别,希望对大家有所帮助,一起跟随小编过来看看吧2018-05-05
spring-data-elasticsearch @Field注解无效的完美解决方案
这篇文章主要介绍了spring-data-elasticsearch @Field注解无效的完美解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2021-07-07
详解SpringBoot 创建定时任务(配合数据库动态执行)
本篇文章主要介绍了SpringBoot 创建定时任务(配合数据库动态执行),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧2017-10-10


最新评论