本文主要介绍“java==和Equalise有什么区别”。在日常操作中,相信很多人对java==和Equalise的区别有疑问。边肖查阅了各种资料,整理出简单易用的操作方法,希望能帮助大家解答“java==和Equalise有什么区别”的疑惑!接下来,请和边肖一起学习!
1.总的来说==和equalse 比较的都是地址值;
2.==当比较基本数据类型和打包类的常量池时,会比较值。
3.equalse是方法,只能作用于对象数据(Integer等封装类也是对象哈),默认也是比较地址值,但是大多数情况下我们是覆写equalse方法来对比其属性值是否一样;
4.但是equalse方法可以被重写。基本类型中封装类Integer和String的equalse方法都是被重写过的,所以比较的是值
5.Integer的常量池很好理解 -128 127,String也有常量池,我们字面创建String a=“xxx”这种都是进入常量池
关于字符串常量池的解释,请参考本文:https://www.cnblogs.com/tongkey/p/8587060.html.
00-1010
分开讲述==和equalse
一、先说==,在比较不同数据的时候效果
比较它们的值是否相等,例如,两个int变量,并比较变量的值是否相同。
00-1010比较引用的地址是否相同,例如,创建两个新的用户对象,并比较两个用户的地址是否相同。
00-1010
1. 基础数据类型:
基本类型的封装类也可以视为对象。无论是否使用常数池,只要一方通过new创建对象,它就是一定是比较的地址值.
以 的整数为例
不要使用常量池:-128127
publicationstationequalstest(){ 0
IntegerA=new integer(1);
IntegerB=new integer(1);
if(A==B){ 0
system . out . println(' A=B ');
}else{
System.out.println('A!=B’;
}
}
输出是:a!=B
使用常量池
publicationstationequalstest(){ 0
IntegerA=new integer(128);
IntegerB=new integer(128);
if(A==B){ 0
system . out . println(' A=B ');
}else{
System.out.println('A!=B’;
}
}
输出是:a!
rong>
3.2基本类型的包装类 不使用new创建对象的时候
以Integer举例
在-128 127的时候,会使用常量池数据,从而比较对象值;不使用常量池的时候,会比较地址值
使用常量池的时候-128 127 public static void equalsTest(){ Integer A=-127; Integer B=-127;; if(A==B){ System.out.println("A=B"); }else{ System.out.println("A!=B"); } } 输出结果为:A=B 不使用常量池的时候,比较的是地址值 public static void equalsTest(){ Integer A=128; Integer B=128;; if(A==B){ System.out.println("A=B"); }else{ System.out.println("A!=B"); } } 输出结果为:A!=B
3.3Integer的特殊情况 Integer在用==对比int类型的时候,无论何时都是对比的值
赋值128,没有使用到常量池 public static void equalsTest(){ Integer A=new Integer(128); int B=128; if(A==B){ System.out.println("A=B"); }else{ System.out.println("A!=B"); } } 输出结果为:A=B 查看源码 发现 Integer只会对int作值的比较 /** * Compares this object to the specified object. The result is * {@code true} if and only if the argument is not * {@code null} and is an {@code Integer} object that * contains the same {@code int} value as this object. * * @param obj the object to compare with. * @return {@code true} if the objects are the same; * {@code false} otherwise. */ public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false; }
3.4 String类型的使用常量池对比的也是值(绝大多数情况都是用到常量池)
我们通常使用String A="hello";这种方式创建的所有变量所有的都进了字符串常量池
这种创建方式都是会使用到常量池 public static void equalsTest(){ String A="hello"; String B="hello"; if(A==B){ System.out.println("A=B"); }else{ System.out.println("A!=B"); } } 输出结果为: A=B 我们通常使用String A="hello";这种方式创建的所有变量所有的都进了字符串常量池 String类的final修饰的,以字面量的形式创建String变量时,jvm会在编译期间就把该字面量(“hello”)放到字符串常量池中,由Java程序启动的时候就已经加载到内存中了。这个字符串常量池的特点就是有且只有一份相同的字面量,如果有其它相同的字面量,jvm则返回这个字面量的引用,如果没有相同的字面量,则在字符串常量池创建这个字面量并返回它的引用
3.5 String类型不使用常量池的情况,比较的是地址值
public static void equalsTest(){ String A="hello"; String B=new String("hello");; if(A==B){ System.out.println("A=B"); }else{ System.out.println("A!=B"); } } 输出结果为:A!=B 通过new创建对象,使用的是新的对象,结果自然不相等 public static void equalsTest(){ String A="hello"; String B=new String("hello"); //B引用变为常量池的hello的引用 B=B.intern(); if(A==B){ System.out.println("A=B"); }else{ System.out.println("A!=B"); } } 输出结果为:A=B
二、equalse是方法,只能作用于对象数据(Integer等封装类也是对象哈),默认也是比较地址值
1.equalse方法默认还是比较地址值。但是可以被重写
在大多数Java类库中的类中 如基本类型中封装类Integer和String的equalse方法都是被重写过的,所以比较的是值
通常我们使用equalse都是自己覆写方法来对比对象内部的属性值是否相同
三、值相同的时候,hashcode不一定相同
结论:hashcode相同,值不一定相同,值相同hashCode一定相同(重写hashCode方法)
1. 为什么ashcode相同,值一定相同,值相同hashCode不一定相同
hashCode是所有java对象的固有方法,如果不重写的话,返回的实际上是该对象在jvm的堆上的内存地址,而不同对象的内存地址肯定不同,所以这个hashCode也就肯定不同了。如果重写了的话,由于采用的算法的问题,有可能导致两个不同对象的hashCode相同。
2.hashCode和equalse的关联关系
hashCode和equals两个方法是有语义关联的,它们需要满足:
A.equals(B)==true --> A.hashCode()==B.hashCode()
因此重写其中一个方法时也需要将另一个也重写。
3.HashCode方法重写需要满足规范
如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。
3.1 hashCode的重写实现需要满足不变性,即一个object的hashCode不能前一会是1,过一会就变成2了。
3.2 hashCode的重写实现最好依赖于对象中的final属性,从而在对象初始化构造后就不再变化。一方面是jvm便于代码优化,可以缓存这个hashCode;另一方面,在使用hashMap或hashSet的场景中,如果使用的key的hashCode会变化,将会导致bug,比如放进去时key.hashCode()=1,等到要取出来时key.hashCode()=2了,就会取不出来原先的数据。
4.hashCode为什么会存在相同的情况
以hashSet举例,hashSet JDK1.8以前底层结构是数组+链表的形式,1.8之后是数组+链表+红黑树
以1.8举例:
在向hashSet集合中添加元素时,需要经过两个步骤
-
计算hashcode并与hashSet数组中的hashcode进行比较
-
如果有相同的hashcode,则对该hash的内容使用equals进行比较,如果不同则存入集合
因此相同的hashcode不一定有相同的值,但是如果值相同,那他的hashcode一定相同
4. 只要使用HashSet存储自定义类型的数据切记要重写equals和hashCode方法
到此,关于“java==和equalse的区别是什么”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/115177.html