==和equals()最大的区别是:一个是运算符,一个是方法,方法可以被重写
hashmap判断两个对象真正相等
hashmap内部主要是通过这两块实现的对比两个数据是否相等,
此时点进equals可以看到java的equals方法也是通过==来实现的
但是一般equals方法都会被重写,例如String类中就把equals重写了
equals方法不能用于判断基本数据类型的变量,如只能用来判断两个对象是否相等。
如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址(==)。
equals
equals用来对比两个对象是内容是否相等
public class Test { public static void main(String args[]) { String Str1 = new String("runoob"); String Str2 = Str1; String Str3 = new String("runoob"); boolean retVal; retVal = Str1.equals( Str2 ); System.out.println("返回值 = " + retVal ); retVal = Str1.equals( Str3 ); System.out.println("返回值 = " + retVal ); } }
返回值 = true 返回值 = true
==
- 如果对比的是基本数据类型,则对比地址是否相等
- 如果对比的是引用数据类型,则对比的是内存地址是否相等
// 例一 String str = "wo"; String str1 = "wo"; System.out.println("例一:" + (str == str1)); // 例二 String str2 = new String("wo"); String str3 = new String("wo"); System.out.println("例二:" + (str2 == str3)); // 例三 int i1 = 1; int i2 = 1; System.out.println("例三:" + (i1 == i2)); // 例四 TestObject t1 = new TestObject(); TestObject t2 = new TestObject(); System.out.println("例四:" + (t1 == t2));
例一:true 例二:false 例三:true 例四:false
使用String str=“wo”,可能创建一个或者不创建对象。如果“wo”在字符串常量池中已经存在,则不会再创建String类型的值为“wo”的对象,而是将str指向这个“wo”对象内存地址,后续无论用这种方式创建多少个指向“wo”的引用,在内存中,都只有一个“wo”内存地址被分配。而==判断的是对象内存的地址,所以例一返回true。下图是用这种方式创建字符串的示例图。
在上图中,栈存放的是字符串的引用,str和str1存放的都是对象“wo”的内存地址,==判断对象时,判断的是他们存储的内存地址是否相同,由上图可见,他们的内存地址是相同的,所以例一输出的是true。
new一个对象
例二的两个字符串都是通过new的方式创建对象的,所以在堆上有两个String对象,且这两个对象指向字符串常量池中的同一个对象“wo”,如上图所示,此时str2和str3存储的对象地址就不相同,所以例二返回的是false。
判断相等总结
hashmap通过两次判断==和equals保证了两个对比数据的绝对相等,如果等于true,那么两个数据的地址和值都是相等的