Java判定相等---==和equals()和“compareTo()”

本文详细解析了Java中'=='、equals()和CompareTo()方法的用法区别,包括基本数据类型比较、对象地址判断及字符串池原理,帮助理解字符串和对象相等的条件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Date:2021.12.29

Author:qyan.li

Reference:https://blog.csdn.net/qq_43576028/article/details/90347117


前言

最近,利用Java学习数据结构,涉及到相等情况的判断,想起曾经阅读过类似知识点,故整理一下,方便后续查看。


一、Java中“==”

Java中等号使用最为普遍,同时也最容易理解,“==”的使用主要分为两种情况:

  • 比较双方为基本数据类型->比较二者的数值大小

    此种情况下主要包含int ,double 等基本数据类型

  • 比较双方为Object或者自定义对象(class)->比较二者在内存中地址是否相同

    Student s1 = new Student("liqiyan",10);
    Student s2 = new Student("liqiyan",10);
    System.out.println(s1 == s2); // output->false
    

    Tips:比较对象为string字符串需注意声明字符串new String的区别

    以程序为例进行说明:

    String s1 = "abc";
    String s2 = "abc";
    String s3 = new String("abc");
    System.out.println(s1 == s2); // ouput -> true
    System.out.println(s1 == s3); // output->false
    

    说明:

    • 在Java中,String存在String pool,其中存放可以共享的字符串对象,在声明一个字符串对象时,会先去其中寻找是否存在相同的String内容,假设存在是不会创建新对象,故此时二者的内存地址相同。
    • 但是new String会重新开辟地址,因此与之前String对象地址不同

二、Java中CompareTo()方法

Java中CompareTo方法可以借助于源码进行分析,顺便提一下,IDEA中获取源码的快捷建,选中命令后,快捷键ctrl+shift+i

/*CompareTo源码*/
public int compareTo(String anotherString) {
	byte v1[] = value;
	byte v2[] = anotherString.value; // 转换为Byte数组
	byte coder = coder();
	if (coder == anotherString.coder()) { // 判断字符编码并比较单个字符ASCII码
		return coder == LATIN1 ? StringLatin1.compareTo(v1, v2)
								: StringUTF16.compareTo(v1, v2);
	}
	return coder == LATIN1 ? StringLatin1.compareToUTF16(v1, v2)
							: StringUTF16.compareToLatin1(v1, v2);
}

关于CompareTo源码的说明:

  • return type为int类型变量
  • 源码大体意思在于将字符串对象转换为Byte数组,逐个比较单个字符的ASCII码,最终返回ASCII的int差值
  • 依据源码分析,CompareTo方法传入为String对象,而非Object

总结一下:CompareTo逐个比较String单个字符的ASCII,并返回ASCII的差值

/*Testing Code*/
String s1 = "abc";
String s2 = "bcd";
String s3 = new String("add");
System.out.println(s1.compareTo(s2)); // output->-1
System.out.println(s1.compareTo(s3)); // output->-2

三、Java中equals()方法

类似于CompareTo方法,equals方法同样借助于sourse code进行分析:

/*equals源码*/
public boolean equals(Object anObject) {
	if (this == anObject) { // 判断地址是否相同
		return true;
	}
    return (anObject instanceof String aString) // 类似于CompareTo逐个字符进行比较
    	&& (!COMPACT_STRINGS || this.coder == aString.coder)
    	&& StringLatin1.equals(value, aString.value);
}

关于equals源码的说明:

  • return type为Boolean类型的变量
  • 判断规则:
    • 首先判断地址是否相等,若地址相同,两对象一定相同
    • 其次根据字符逐个进行判断,最终返回Boolean类型的变量
  • 依据源码进行分析,equals方法传入Object对象进行判断

总结一下:个人认为equals方法与CompareTo方法类似,先行加入地址判断,而后根据字符逐个分析

/*Testing code*/
String s1 = "abc";
String s2 = "bcd";
String s3 = new String("abc");
System.out.println(s1.equals(s3)); // output->true
System.out.println(s1.equals(s2)); // output->false
### Bigdecimal `compareTo` `equals` 方法的区别 #### 值与标度的比较 当涉及到数值类型的精确比较时,特别是对于带有不同精度的情况,`BigDecimal` 提供了两种不同的方式来判断两个数是否相同。其中一种是通过 `equals()` 来实现严格意义上的相等性检测;而另一种则是利用 `compareTo()` 进行基于值本身的对比。 - **`equals()` 方法** - 此方法不仅考虑数值本身还关注其标度(即小数位)。因此即使两个 `BigDecimal` 实例表示相同的数学量级,但如果它们的小数部分长度不一样,则会被认为不是同一个对象[^2]。 ```java // 使用 equals 方法的例子 BigDecimal num1 = new BigDecimal("1.0"); BigDecimal num2 = new BigDecimal("1"); System.out.println(num1.equals(num2)); // 输出 false ``` - **`compareTo()` 方法** - 只关心实际代表的数量而不受具体表现形式的影响。这意味着只要两个数字在数学意义上相等——无论怎样表达出来的——都会被认为是相等的[^1]。 ```java // 使用 compareTo 方法的例子 BigDecimal decimal = new BigDecimal("0E-10"); BigDecimal zero = BigDecimal.ZERO; if (decimal.compareTo(zero) == 0){ System.out.println("相等"); }else { System.out.println("不等"); } ``` 此外值得注意的是,除了用于简单的相等测试外,`compareTo()` 同样可以用来确定一个 `BigDecimal` 是否大于或小于另一个实例,并且支持指定上下文环境下的舍入模式[^3]。 综上所述,在大多数情况下推荐使用 `compareTo()` 而非 `equals()` 对于 `BigDecimal` 类型的数据进行逻辑上的相等判定操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值