==与equals的主要区别是:
- ==常用于比较原生类型,而equals()方法用于检查对象的相等性。
- 如果==和equals()用于比较对象,当两个引用地址相同,==返回true。而equals()可以返回true或者false主要取决于重写实现。
最常见的一个例子,字符串的比较,不同情况==和equals()返回不同的结果。
equals()方法最重要的一点是,能够根据业务要求去重写,按照自定义规则去判断两个对象是否相等。
重写equals()方法的时候,要注意一下hashCode是否会因为对象的属性改变而改变,否则在使用散列集合储存该对象的时候会碰到坑!!理解equals()方法的存在是很重要的。
1.1 字符串比较
1.1.1 字符串字面量比较
String s1 = "hello";
String s2 = "hello";
String s3 = "he" + "llo";
System.out.println(s1 == s2); // true - 指向字符串常量池的同一个对象
System.out.println(s1 == s3); // true - 编译期优化,同样指向常量池
System.out.println(s1.equals(s2)); // true - 内容相同
System.out.println(s1.equals(s3)); // true - 内容相同
1.1.2 new String() 创建对象
String s1 = "hello";
String s2 = new String("hello");
String s3 = new String("hello");
System.out.println(s1 == s2); // false - s1在常量池,s2在堆内存
System.out.println(s2 == s3); // false - 两个不同的堆内存对象
System.out.println(s1.equals(s2)); // true - 内容相同
System.out.println(s2.equals(s3)); // true - 内容相同
1.1.3 运行时拼接的字符串
String s1 = "hello";
String s2 = "he";
String s3 = s2 + "llo"; // 运行时拼接
System.out.println(s1 == s3); // false - s3在堆内存中
System.out.println(s1.equals(s3)); // true - 内容相同
1.1.4 intern() 方法的影响
String s1 = "hello";
String s2 = new String("hello");
String s3 = s2.intern(); // 将s2放入常量池
System.out.println(s1 == s2); // false
System.out.println(s1 == s3); // true - intern()后指向同一个常量池对象
System.out.println(s1.equals(s2)); // true
1.1.5 更复杂的例子
String s1 = "java";
String s2 = "ja";
String s3 = "va";
String s4 = s2 + s3; // 运行时拼接
String s5 = "ja" + "va"; // 编译期优化
final String s6 = "ja";
String s7 = s6 + "va"; // 编译期优化(s6是final)
System.out.println(s1 == s4); // false
System.out.println(s1 == s5); // true
System.out.println(s1 == s7); // true
System.out.println(s1.equals(s4)); // true