简析Java 中equals和==的区别
Java 中equals和==的区别
一. 对于基本类型的变量。"=="和"equal"的区别
??? (1)“==”对于基本数据类型,是判断两个变量的值是否相等。只要他们的值相同,==的比较就返回true。
?“equal”不能用于基本数据类型。只能用于类变量。对于基本数据类型要用其包装类。比如Boolean.Character.Byte.Shot.Integer.Longer.Float.Double等包装类,在这里==比较的是地址,看二者是否引用同一个堆内存空间,如果是,则返回true。而“equal”是比较内容的。
?
二 .对于对象变量,"=="和"equal"的区别
???“==”比较的是值,这个值也就是内存中存放的对象的(堆)内存地址。所以,如果即使对象的值相等,但是他们的内存地址不同,==比较的结果还是为false。故“==”用于比较两个变量的值是否相等,就是判断它们是否是同一份内存数据。而不是判断变量引用的对象是否相等
“equal”用于比较两个对象是否相等,也就是双方对象中的内容是否相等,不是比较内存地址。
所以所有需要进行对像是否相同的比较,都要用到equals方法。而equals的使用,只依赖于所使用的那个类是如何实现(重写)该方法的。当然根据需要,我们可以自行实现是比较对象内的内容值是否相同,或者直接比较对象的内存地址,当然还可以是结合二者的比较形式,例如,我们最常见的String类型中的“equals”方法,
??
我们都知道java中所有的类都默认继承于Object,所以若某类没有重载它的“equals”方法,则默认使用Object的equals方法,而Object的equals方法,是直接比较对象的内存地址。
public boolean equals(Object obj) {
??? return (this == obj);
?}
所以对于“equals”的比较方式,是取决于类是否重载了Object类中的方法,若未重载,则与==的比较方式相同。
?
三 、几个重载的equals方法的使用
1.对于字符串变量来说,使用“==”和“equals()”方法比较字符串时,这个前面已经说过了,其比较方法是不同的。
“==”比较两个变量本身的值,即两个对象在内存中的首地址。
“equals()”比较字符串中所包含的内容是否相同。
? 听老师讲解说,在虚拟机中,是存在字符串池的。它里面保存着String对象。
??
?? 在上面的代码中,当我们创建str1和str2时,这两个对象就是加入到字符串池中的。而且当创建好了第一个str1时,就将“abc”存放在里面,当创建第二个str2时,虚拟机就会首先去它的字符串池中搜索,看能否找到对应的,也就是相同的字符串,如果存在,就直接将已经存在的那个对象的引用给要创建的对象的引用。若不存在,则创建一个新的对象,并返回一个新对象的引用给要创建的对象的引用。
? 所以上面的第一条输出语句中,返回的是true,但是为什么第三条输出语句返回的是false呢?这是因为当创建str3时,我们用的是new,而这种方法创建的字符串是不放在那个池里面的。故得到的结果会是false了。而且我们应该知道,只要是使用了new的,就是一个新的对象了。???
?????
2.对于队列list中的比较。
?? “==”比较两个变量本身的值,即两个对象在内存中的首地址。
在这里我们还需要注意的是list存储的对象的类型,如果两个list容器存放的是不同的类型对象,则不能进行比较。这其实就相当于比较不同类型的对象,这是不允许的,程序编译时会报强制类型转换的错误。当然也可以用来比较同一个容器中的不同对象是否指向同一个内存地址。
“equals()”比较会先比较他们的内存地址是否相同,若不是,则看括号中的对象是否是list的实例,若不是则直接返回false,若是,遍历他们中的对象来进行比较。下面是list中重写的equals方法。
??
?
???3.“set”中的比较
因为set本身就是无序的,我们必须通过迭代器才能取得它里面的元素,所以,在set中就不存在e.equals(e1)满足的情况,如果使用“==”比较两个set容器对象,我们都知道它的结果肯定是false。因为,它们都是新创建的对象,内存地址不一样,所以使用“==”的结果的结果是false就不奇怪了。
“equals“的比较方法也是重载的,方法的代码如下:
?我们可以知道,它们是先比较内存地址的,若相同则肯定是同一份数据,直接返回true了。若不是,则需要判断括号中的是不是set的实例,若不是则肯定不需要在比较了,直接返回false就行了。因为它们都不是同一种类型的比较了。若是两个set的实例做比较,则首先看它们大小是否相同,若大小不同了,我们也就知道答案了。在大小相同的情况下,再比较它们的内容,所以这里可以使用set里面的containsAll()方法来比较更快些。
?
?