java 中的 ==、equals 和 hashcode(更新中)

2 篇文章 0 订阅

1. == 运算符

"==" 运算符用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量(例如:String s = new String() )是否相等,只能使用 "==" 运算符。

基本数据类型:int,short,long,boolean,char,float,double,byte

引用变量:·

String s = new String();

变量s占用了一块储存空间,而new String() 则存储在另外一块存储空间里(这里涉及到了两块内存),此时,变量s所对应的内存中的存储的数值就是对象占用的那块内存的首地址。

对于指向对象类型的变量,如果要比较两个变量是否指向同一个对象,那么要看这两个变量所对应的内存中的数值是否相等(这两个对象是否指向同一块存储空间,这时候就可以用"=="运算符进行比较。但是,如果要比较的是两个对象的内容是否相等,那么用"=="运算符就无法实现)。

那么问题来了,"=="运算符不能比较对象的内容,那要用什么呢?

我们先来看看equals的概念

2.equals

equals是Object类提供的方法之一,因为每一个Java类都继承自Object类,所以每一个对象都具有equals这个方法。因为Object类中定义的equals(Object)方法是直接使用"=="运算符比较的两个对象, 所以在没有覆盖equals(Object) 方法的情况下, equals(Object) 与“==”运算符一样,比较的是引用

String s1 = new String("Hello");
String s2 = new String("Hello");

从代码输出结果结合上面的概念就比较容易理解:

== 返回false是因为 ==比较的是字符串的内存地址(引用)

equals返回false是因为 equals比较的是字符串的内容(值)

注:

这里可能有人会有疑惑为什么 equals 为什么不是返回false啊?不是说没有覆盖equals(Object) 方法的情况下, equals(Object) 与“==”运算符一样,比较的是引用吗?

那是因为Sun的API已经为String类重载了equals方法了,所以实际上已经被覆盖了。

下面的代码就是equals没有被覆盖的结果

public class Test {
	private int batch;
	public Test(int batch) {
		this.batch = batch;
	}

	public static void main(String[] args) {
		Test c1 = new Test(1);
		Test c2 = new Test(1);
		System.out.println(c1.equals(c2));
		System.out.println(c1 == c2);
	}


}

可以看到两个结果都是false,但是equlas也是false的原因是因为equlas没有被重载没被重载的话实际上和 == 是一个作用。

3.hashCode方法

hashCode()方法是从Object类中继承过来的,也用来鉴定两个对象是否相等。Object类中的haseCode()方法返回对象在内存中地址转换成一个int值,所以如果没有重写hashCode()方法,那么任何对象的hashCode方法都是不相等的。

一般来说比较少用hashCode()来判断,因为它返回的是一个int值,相比其他两个没有这么直观。

4.== 和 equals使用对比

== equals 两个方法都可以用来比较字符串,但是 == 要慎重使用(实际上就是不要用==来比较字符串,因为有可能会出现bug,而且可能是间歇性的出现),因为两个相同的字符串用 == 来比较也是会出现 false的现象。用代码来验证这个问题。

        String a = "abcd";
        String b = "ab";
        String c = "cd";
        String e = b + c;
        String f = "abcdef";
        String g = f.substring(0,4);
        System.out.println("abcd".equals(a));
        System.out.println("abcd".equals(e));
        System.out.println("abcd".equals(g));
        System.out.println();
        System.out.println("abcd" == a);
        System.out.println("abcd" == e);
        System.out.println("abcd" == g);

注:a 是完整的“abcd” , e是通过 + 来拼接成“abcd” ,  g是通过substring字符串截取成“abcd”

1. 首先我们从equals 来看,可以看到三个对比都是true

2. 再来看 == ,第二、三个比较都是false,可以得出结论通过 +号拼接substring截取 是不能用 == 来比较的。

结论

equals比较的是字符串的内容(值),因为上面4个字符串的内容都是 abcd ,所以返回的结果也都是true。

而 == 比较的是字符串的内存地址(引用),这里通过 +号拼接substring截取 的两种方式改变了字符串的内存地址,理所当然,返回的结果就变为false。

也可以用这种方式来记忆,虚拟机始终将相同的字符串共享,就可以使用 == 运算符来检测是否相等。但是 +号拼接substring截取 返回的结果并不是共享的。所以在程序中尽量不使用 == 来比较字符串。(使用==来比较字符串容易出现随机的、间歇性的bug)

附上一个比较字符串(不区分大小写)方法: equalsIgnoreCase

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值