Java中比较对象是否相同最常用的方式就是equals和'=='.很显然这是不同的.
首先我们要了解一下JVM的基本构造.此处涉及到的主要是jvm的虚拟机栈和堆heap..Java文件经过编译之后生成Class文件.Class文件通过类加载器Class Loader将资源放入JVM不同区域.栈区保存对象引用地址和基本类型变量(int,boolean..),而堆区保存具体对象信息.
1.==
首先.如果比较的是基本类型变量,直接比较栈区的值,很显然相等
int a = 1
int b = 1
return a==b
如果比较的是包装类,直接new一个对象,比较堆地址,不相等
Integer a = new Integer(1)
Integer a2 = new Integer(1)
直接定义Integer对象时,编译器会调用valueOf()自动装箱(反编译结果).当值在-128和127之外时,直接new一个对象.很显然堆地址不同.
Integer a =1;
low=-128 high=127
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
而之内的范围,翻译一下就是首次使用的时候会初始化缓存生成对象.堆地址已经固定了,自然-127-128之间的Integer可以直接比较.
其他的也类似可自行查看.
/**
* Cache to support the object identity semantics of autoboxing for values between
* -128 and 127 (inclusive) as required by JLS.
*
* The cache is initialized on first usage. The size of the cache
* may be controlled by the {@code -XX:AutoBoxCacheMax=} option.
* During VM initialization, java.lang.Integer.IntegerCache.high property
* may be set and saved in the private system properties in the
* sun.misc.VM class.
*/
如果比较的是非基本变量,则比较他们的栈区所指向的堆地址.两次String生成了两个String类的实例,很显然他们指向的堆地址是不一样的.
String a ="1"; String b = "1";
2.equals
java.lang.Object是Java根类.如果一个类没有指定父类,默认继承Object类.比较堆指向地址.
public boolean equals(Object obj) { return (this == obj); }
当然,大部分类都重写的equals方法.
demo:String.class
1.首先和自身比较肯定是true
2.instanceof判断入参对象是否是String.class实例
3.比较字符串长度是否相同
4.从字符串头部开始比较每一位是否相同
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
3.hashcode
hashcode可以理解为一个加密算法根据值得到一个密文来大致确定一个对象 .同一个对象的hashcode肯定相同但是哈希码相同的不一定是同一个对象.
hashcode主要运用在在散列如HashMap,HashSet中.
常用的数据结构如:
- 数组,基于索引的有序数据结构,连续的内存空间,因此查询很快.数组初始化固定长度,数组插入数据时,修改速度不尽人意.
- 链表,基于指针,不连续内存空间,插入迅速,但是查找缓慢.
散列结合了数组和列表.如果出现哈希碰撞,在同一个位置使用链表或红黑树解决冲突.因此显而易见,不能拿hashcode来判断两个对象是否相等.