1. 定义
1.1. ==是什么?
在Java中,== 是一个比较运算符,用于比较两个值是否相等。它可以用于比较基本数据类型(如 int、double、char 等)和引用类型(如 String、Integer、自定义的类引用等)。
- 比较基本数据类型
int num1 = 1;
int num2 = 1;
System.out.println(num1 == num2);
- 比较引用类型
User user1 = new User();
User user2 = new User();
System.out.println(user1 == user2);
- 比较基本数据类型和引用类型
//自动拆箱,比较基本数据类型的值
int i = 128;
Integer j = 128;
System.out.println(i == j);
1.2. equals()是什么?
在 Java 中,equals() 方法是Object类的一个方法,被继承到了所有其他类中。它用于比较两个对象是否相等。
2. 区别
2.1. 比较的对象类型不同:
-
- == 操作符用于比较两个对象的引用是否相等,即判断是否指向同一块内存地址。
- equals() 方法用于比较对象的内容是否相等,默认情况下,它与 == 操作符的作用相同,即比较两个对象的引用是否相等。
2.2. 实现方式不同:
-
- == 操作符是一个运算符,对于基本数据类型,它比较的是值是否相等;对于引用类型,它比较的是引用地址是否相等。
- equals() 方法是一个方法,其实现可以由开发人员根据实际需求进行重写。在默认情况下,equals() 方法与 == 操作符的行为相同,但可以通过重写该方法来改变对象之间的比较逻辑。
2.3. 使用的场景不同:
-
- == 操作符通常用于比较基本数据类型的值或判断两个对象的引用是否相等。
- equals() 方法通常用于比较两个对象的内容是否相等,例如,字符串、集合类等。
3. equals重写
3.1. String类重写
为什么重写?
但对于字符串这种常用的引用类型,我们通常希望比较的是字符串的内容是否相等,而不仅仅是比较引用地址。
面试小测:
String str1 = "Hello";
String str4 = new String("Hello");
String str5 = new String("Hello");
System.out.println(str1.equals(str4));
//虽然str1和str4的内容相同,但它们分别引用了不同的字符串对象,
//str1引用的对象来自字符串常量池,str4引用的对象来自堆内存。
//因此,str1==str4的比较结果为false
System.out.println(str1==str4);
System.out.println(str4==str5);
System.out.println(str4.equals(str5));
String str2 = "Hello"; // 字符串常量池中创建字符串对象 "Hello"
String str3 = "Hello"; // 直接从字符串常量池中获取 "Hello" 的引用
System.out.println(str2 == str3); // true,比较引用地址,指向同一个对象
/*
true
false
false
true
*/
3.2. Integer重写
为什么重写?
为了实现我们通常期望的整数值比较。
面试小测:
Integer num1 = 127;
Integer num2 = 127;
System.out.println(num1 == num2);
Integer num3 = 128;
Integer num4 = 128;
System.out.println(num3 == num4);
System.out.println(num3.equals(num4));
Integer缓存池
在Java中,为了提高int和Integer类型的性能,JVM使用了缓存来存储常用的整数值。这个缓存池被称为Integer缓存池。
Integer缓存池中默认缓存了从-128到127之间的整数值对应的Integer对象。当我们通过自动装箱或valueOf()方法创建一个整数值相同的Integer对象时,如果该值在缓存池范围内,JVM会直接返回缓存中的对象,而不是再创建一个新的对象。
// 输出: true,同一对象,从缓存中获取
// 输出: false,不同对象,超出缓存范围
4. 扩展-为什么重写equals方法一般都会重写hashcode方法
4.1. hashcode是什么?
hashCode()方法是Java中Object类的一个方法,它返回当前对象的哈希码(整数值),用于在哈希表等数据结构中进行快速查找。
4.2. 原因
根据Java规范,如果两个对象通过equals()方法判断相等,那么它们的hashCode()方法应该返回相同的值。换句话说,如果两个对象相等(根据equals()定义),则它们的哈希码(通过hashCode()获取)应该相等。
如果我们重写了一个类的equals()方法但没有重写hashCode()方法,那么在使用哈希表的情况下可能会导致不一致的结果。例如,将该对象放入哈希表中时,它的哈希码可能发生变化,导致无法正确地检索对象。
因此,为了保证在使用哈希表等数据结构时对象能够正常工作,我们应该始终重写hashCode()方法,使其与equals()方法保持一致。
重写equals()方法是为了定义对象的相等性,而重写hashCode()方法是为了确保相等的对象具有相同的哈希码,在使用哈希表等数据结构时能够正常工作。
5. 总结
- 在equals未重写的情况下:
==可用于基本数据类型和引用类型的比较,而equals只能用于引用类型的比较。
- 在equals重写的情况下:
==一般用于基本数据类型和引用类型的地址的比较,equals则一般用于引用对象内容的比较。
- 为了提高Integer类型的性能,JVM使用了缓存来存储常用的整数值。
- 重写的equals的情况下一般也重写hashcode方法。
- 重写equals()方法是为了定义对象的相等性,而重写hashCode()方法是为了确保相等的对象具有相同的哈希码,在使用哈希表等数据结构时能够正常工作。