Java中的比较对象
我们常常会遇到 == 和 equals()方法 用来比较一些值 以及 对象。那么他们的区别是什么?
首先,equals()方法是属于Java中object类的,其作用是比较两个对象的引用地址
而= =也是比较两个对象的引用地址,而不是比较对象的属性。
一、
我们首先来说说equals(),先从源码入手:
public boolean equals(Object obj) {
return (this == obj);
}
}
equals()方法里进行比较时运用了完全相同运算符= =(比较对象的引用/地址),因此下面这个例子输出为false;因为两个Man对象的内存地址不一样
public class Man {
String geneticCode;
public static void main(String[] args) {
Man man1 = new Man();
man1.geneticCode = "111122223333";
Man man2 = new Man();
man2.geneticCode = "111122223333";
System.out.println(man1.equals(man2));
}
}
但我们可以进行equals()方法改写
public class Man {
int dnaCode;
public boolean equals(Man man) {
return this.dnaCode == man.dnaCode;
}
public static void main(String[] args) {
Man man1 = new Man();
man1.dnaCode = 1111222233;
Man man2 = new Man();
man2.dnaCode = 1111222233;
System.out.println(man1.equals(man2));
}
}
二、字符串
表现字符串有两种方式
public class Main {
public static void main(String[] args) {
String s1 = "CodeGym is the best website for learning Java!";
String s2 = new String("CodeGym is the best website for learning Java!");
System.out.println(s1 == s2);
}
}
其中s1是常量,s2是字符串对象;原因就在这里,创建字符串常量s1时,它会被储存在常量池中的字符串池,用来节省内存,当你再创建一个String s2 = "CodeGym is the best website for learning Java!";
时,s1和s3都会指向同一个地址,如图
而当你使用new创建字符串对象时,Java会为该对象强制分配新的内存区域,并且不会出现在字符串池中
因此,以下代码输出为true
public class Main {
public static void main(String[] args) {
String s1 = "CodeGym is the best website for learning Java!";
String s2 = "CodeGym is the best website for learning Java!";
System.out.println(s1 == s2);
}
}
那么为什么用equals()反而又是true呢?前面不是说了equals()方法是比较对象的引用吗?上图已经很明显,常量和对象是不同的地址,即使他们讲的话是一样的。那是因为,String中的equals()方法已经被改写!这个方法被用来比较值,如下
public class Main {
public static void main(String[] args) {
String s1 = "CodeGym is the best website for learning Java!";
String s2 = new String("CodeGym is the best website for learning Java!");
System.out.println(s1.equals(s2));
}
}
控制台输出为 真;
equals还有个延伸的方法equalsIgnoreCase(),可以直接忽略大小写,从而比较字符的顺序
public class Main {
public static void main(String[] args) {
String address1 = "2311 Broadway Street, San Francisco";
String address2 = new String("2311 BROADWAY STREET, SAN FRANCISCO");
System.out.println(address1.equalsIgnoreCase(address2));
}
}
控制台输出为 true
延伸:
String.intern()方法:
它检查字符串池中是否有匹配的字符串
如果存在,它将返回对池中字符串的引用
如果没有,它将字符串添加到字符串池并返回对其的引用
public class Main {
public static void main(String[] args) {
String s1 = "CodeGym is the best website for learning Java!";
String s2 = new String("CodeGym is the best website for learning Java!");
System.out.println(s1 == s2.intern());
}
}
控制台输出为 true
总结:
==用法:比较引用类型的内存地址是否相等;比较基本类型的值是否相等
equals()用法:默认作用是比较内存地址,适当情况下可进行改写。