equals和==区别

在Java中,equals和==是两种用于比较对象的操作符,但它们的行为和用途有所不同。
        == 操作符:
        == 操作符用于比较两个对象的引用是否相等,即它们是否指向同一个内存地址。
        对于基本数据类型(如int、double、char等),== 比较的是它们的值是否相等。
        对于引用数据类型(如对象、数组等),== 比较的是它们的引用是否指向同一个对象。


          equals 方法:
equals 方法是Object类中的一个方法,用于比较两个对象的内容是否相等。
在自定义类中,通常需要重写equals方法,以提供自定义的对象比较逻辑。
如果没有重写equals方法,默认情况下,它的行为与==操作符相同,即比较引用是否相等。

这里需要知道大概的内存分布

Java提供的所有类中,绝大多数类都重写了equals()方法,equals方法进行了重写则是用来比较指向的对象所存储的内容是否相等

Integer a= 127 Integer b = 127 相等吗
对于对象引用类型: == 比较的是对象的内存地址。
对于基本数据类型: == 比较的是值。如果整型字面量的值在 -128 127 之间,那么自动装箱时不会 new
新的 Integer 对象,而是直接引用常量池中的 Integer 对象,超过范围 a1==b1 的结果是 false

Integer a = 1Integer f = new Integer(1)int c = 1有什么区别

int c = 1:

  • int是基本数据类型,直接存储数值 1 在栈内存中,在程序运行时,其值直接存储在栈空间中,访问和操作速度较快。

Integer a = 1:

Integer变量指向的是 java 常量池中的对象

  • Integerint的包装类,属于引用数据类型。当使用Integer a = 1这种方式赋值时,Java 会自动进行装箱操作,实际上是调用了Integer.valueOf(1)方法,将基本数据类型int的值 1 转换为Integer对象。这个Integer对象可能会被缓存在Integer类的内部缓存中(缓存范围一般是 - 128 到 127),如果在这个范围内,会直接返回缓存中的对象,否则会创建新的Integer对象并存储在堆内存中,而变量a存储的是这个Integer对象的引用,存放在栈内存中。
  • 当使用==比较两个Integer对象时,如果两个对象在缓存范围内且是同一个对象,则返回true;否则,即使两个对象的值相等,==也会返回false。例如Integer a = 1; Integer b = 1; System.out.println(a == b);会返回true,但如果Integer a = 128; Integer b = 128; System.out.println(a == b);则会返回false。如果要比较两个Integer对象的值是否相等,应该使用equals()方法,如System.out.println(a.equals(b));

Integer f = new Integer(1)

new Integer() 的变量指向堆中新建的对象,两者在内存中的地址不同

  • 显式地使用new关键字创建一个新的Integer对象,无论传入的值是否在缓存范围内,都会在堆内存中创建一个新的Integer对象,然后变量f存储的是这个新创建的Integer对象在堆内存中的引用,该引用存放在栈内存中。
  • 因为每次都是新创建的对象,所以使用==比较时,除非是同一个对象引用,否则总是返回false。同样需要使用equals()方法来比较值是否相等

Integer a = 1;  // 这里会自动装箱

Integer b = 1;
Integer f = new Integer(1);
Integer g = new Integer(1);
int c = 1;
int d = 1;
System.out.println(a==d); //  a会自动拆箱
System.out.println(a.equals(d)); //  d会自动装修
System.out.println(a == b); //
System.out.println(a.equals(b));  // true

System.out.println(f == a); // false


System.out.println(f == c); // true
System.out.println(f.equals(c));
System.out.println(f.equals(a));
System.out.println(f.equals(g));

判断下列的输出结果
String aaa = new String("ab"); // a 为一个引用
String bbb= new String("ab"); // b为另一个引用,对象的内容一样
String aa = "ab"; // 放在常量池中
String bb = "ab"; // 从常量池中查找

System.out.println(aa.equals(aaa));
System.out.println(aa==bb);
System.out.println(aa.equals(bb));
System.out.println(aaa==bb);
System.out.println(aaa==bbb);
System.out.println(aaa.equals(bbb));
hashCode equals 重要
HashSet 如何检查重复
两个对象的 hashCode() 相同,则 equals() 也一定为 true ,对吗?
hashCode equals 方法的关系
面试官可能会问你: 你重写过 hashcode equals 么,为什么重写 equals 时 必须重写 hashCode 方 法?

hashCode()介绍

hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个 int 整 数。这个哈希码的作用是
确定该对象在哈希表中的索引位置。 hashCode() 定义 在 JDK Object.java 中,这就意味着 Java 中的任何
类都包含有 hashCode() 函数。
散列表存储的是键值对 (key-value) ,它的特点是:能根据 快速的检索出 对应的 。这其中就利用
到了散列码!可以快速找到所需要的对象

一个对象肯定有物理地址,对象的物理地址跟这个hashcode地址不一样,hashcode代表对象的地址说的是对象在hash表中的位置,物理地址说的对象存放在内存中的地址,那么对象如何得到hashcode呢?

通过对象的内部地址(也就是物理地址)转换成一个整数,然后该整数通过hash函数的算法就得到了hashcode。所以,hashcode是什么呢?就是在hash表中对应的位置。

从hash表中的查找效率更高!!!!

简单来说

如果两个对象的hashCode()相等,那么他们的equals()不一定相等。
如果两个对象的equals()相等,那么他们的hashCode()必定相等。

因为equals可以看作比较的是内存中的数据

hashCode是把内存中的数据映射到hash表中,表中的数据相等,内存中不一定相等

内存中的相等,表中的一定相等

在没有 hashCode的情况下,在 Set集合中存储1000个对象的话需要用 equals来比较对象的值是否重复, 我们知道 Set是不允许重复对象存在的, 那么当这一千个对象都不重复的情况下, 第1000个对象的存储需要调用1000次 equals去进行比较,这是非常低效的。

而hashCode能解决这种问题,对象的存储不再是顺序存放,而是通过 hashCode直接计算出存储的位置, (可以理解为内存地址,虽然并不是) 之后新对象在存储的时候如果 hashCode跟之前的没有重复则直接存储,如果重复了则用 equals()校验是否相等, 如果不相等的话,以 HashMap作为例子,默认是在同一个地址上用链表存储起来新的对象,

### Java 中 `equal` `equals` 方法的区别Java编程语言中,存在一些误解关于`equal``equals`方法之间的差异。实际上,在标准库以及官方文档中并没有名为`equal`的方法;这里可能存在混淆的是`==`运算符与`equals()`方法间的不同。 #### `==` 运算符的作用 当使用`==`来比较两个变量时,如果是基本数据类型,则会直接对比它们的具体数值是否相同[^2]。但对于引用类型的对象而言,`==`则用来检验这两个引用是不是指向堆内存中的同一位置——也就是检查两者是否代表完全相同的对象实例而不是其内部状态或属性上的相似性[^4]。 #### `equals()` 方法的功能 相比之下,`equals()`是一个由所有类间接继承自顶级父类`Object`所提供的成员函数[^1]。它的原始行为同样也是做引用级别的相等测试,这跟`==`针对对象的情况是一致的。不过为了满足特定应用场合下更细致化的匹配需求(比如字符串内容的一致与否),很多内置的数据结构已经对该方法进行了覆盖实现以便能够按照元素的实际组成来进行判定而非仅仅依据身份标识[^3]。 对于开发者自行设计的应用程序组件来说,如果希望创建出来的实体能够在语义层面上被合理地认为是“相等”的话,那么就应当适当地重载这个来自祖先接口的规定动作以体现业务逻辑所要求的确切含义。 ```java public class Person { private String name; public boolean equals(Object obj){ if (this == obj) return true; // 自身比较优化 if (!(obj instanceof Person)) return false; Person other = (Person)obj; return this.name.equals(other.getName()); } // Getter and Setter omitted... } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值