在面试的时候很多时候会问到“==”和equals()对于很多人来说都已经很了解了,对于我来说似乎和新的知识点一样。下面就来分析一下:
- “==”是干什么的呢? 答案:是比较两个变量的值是否相等,在java中有8中基本类型:byte,short,int,long,chart,boolean,float,double;对于基本类型的数据使用“==”的时候就会比较的是他们本身的值。此处不再举例便很容易明白。 有人会很奇怪String类型,它不是基本数据类型,在使用“==”的时候为什么有时候返回的是true有时候返回的是false呢?接下来进行说明一下: String str1 = "test"; String str2 = "test"; System.out.println(str1==str2); 这个时候的结果是true;为什么呢?这个时候可以肯定的时候比较的时候依然比较的是内存地址,说明此刻str1和str2指向的是同一对象所以此处相等。 String str3 = new String("test"); String str4 = new String("test"); System.out.println(str3==str4); 这个时候的结果是false;这个时候str3和str4比较内存地址的时候不同所以返回的是false,那么在使用“==”做比较的时候结果是对的呢?就不得不说“字符串缓冲池”,在程序运行的时候str2="test"的时候会在String的缓冲池中寻找相同值的对象,由于str1=“test”已经被放到了字符串缓冲池中,所以在str2得到的是str1的引用所以“==”得到的结果是true; 当我们使用了new时候就是告诉虚拟机,需要创建一个新的对象,这个时候就会在堆和栈中分别创建出对象和相应对象的引用。所以,两个不同的地址“==”的时候,一定是false(内存有一定的浪费);如果想要避免相同情况的内存的浪费可以是用str4=str3.intern();这个函数是对字符串缓冲池进行了检查然后将str3内容相的缓冲池的值给返回。
2.“equals()”
在作对象内容进行比较的时候显然“==”是不行的,所以equals()方法随之诞生了。 在基类Object中有方法equals()实现方式,此刻比较的仍然是内存地址: public boolean equals(Object paramObject) { return (this == paramObject); } 在封装的对象类型很多都已经重写了Object中equals方法那么简单看两个: String类中的:
public boolean equals(Object paramObject) {
if (this == paramObject)
return true;
if (paramObject instanceof String) {
String str = (String) paramObject;
int i = this.count;
if (i == str.count) {
char[] arrayOfChar1 = this.value;
char[] arrayOfChar2 = str.value;
int j = this.offset;
int k = str.offset;
while (i-- != 0)
if (arrayOfChar1[(j++)] != arrayOfChar2[(k++)])
return false;
return true;
}
}
return false;
}
String类中的equals()方法首先比较的是内存地址,然后是字符串长度,然后逐个字符进行比较。 Integer类中:
public boolean equals(Object paramObject) {
if (paramObject instanceof Integer)
return (this.value == ((Integer) paramObject).intValue());
return false;
}
此刻比较的也是内容,所以当我们创建类的时候,对象做比较的时候需要重写equals方法,因为一般如果使用java中的Map对象进行存储时,他会自动调用hashCode方法来比较两个对象是否相等。
3.“hashcode()”
所以如果我们对equals方法进行了重写,建议一定要对hashCode方法重写,以保证相同的对象返回相同的hash值,不同的对象返回不同的hash值。重写hashcode()方法的目的是提高查找效率。 设计hashCode()时最重要的因素就是:无论何时,对同一个对象调用hashCode()都应该产生同样的值。如果在讲一个对象用put()添加进HashMap时产生一个hashCdoe值,而用get()取出时却产生了另一个hashCode值,那么就无法获取该对象了。所以如果你的hashCode方法依赖于对象中易变的数据,用户就要当心了,因为此数据发生变化时,hashCode()方法就会生成一个不同的散列码。 因此一定要注意:千万不能改变生产hashcode的相关变量,这个会造成内存泄漏,永远get不到存放在内存中的对象。
来源:oschina
链接:https://my.oschina.net/u/1766153/blog/739873