一、Java中==和equals的區(qū)別
1.==
1)"=="如果比較的是基本數(shù)據(jù)類型(byte short char boolean int long double float),對(duì)比的是值虽界,因此是相等的炫加,例如
int num1 = 34;
int num2 = 34;
char c1 = 'a';
char c2 = 'a';
char c3 = 'b';
System.out.println("num1 == num2: "+(num1 == num2));
System.out.println("c1 == c2: "+(c1 == c2));
System.out.println("c1 == c3: "+(c1 == c3));
結(jié)果:
num1 == num2: true
c1 == c2: true
c1 == c3: false
2)如果比較的是對(duì)象則對(duì)比的是對(duì)象的地址值,例如
String s1 = new String("hello");
String s2 = new String("hello");
String s3 = "hello";
String s4 = "hello";
System.out.println("s1 == s2: "+(s1 == s2));
System.out.println("s1 == s3: "+(s1 == s3));
System.out.println("s2 == s3: "+(s2 == s3));
System.out.println("s3 == s4: "+(s3 == s4));
結(jié)果:
s1 == s2: false
s1 == s3: false
s2 == s3: false
s3 == s4: true
2.equals
1)對(duì)于字符串常量來(lái)說(shuō)泻轰,equals比較的是對(duì)象兩邊的內(nèi)容技肩,如果內(nèi)容相同則返回true
String s1 = new String("hello");
String s2 = new String("hello");
String s3 = "hello";
String s4 = "hello";
System.out.println("s1.equals(s2): "+s1.equals(s2));
System.out.println("s1.equals(s3): "+s1.equals(s3));
System.out.println("s3.equals(s4): "+s3.equals(s4));
結(jié)果:
s1.equals(s2): true
s1.equals(s3): true
s3.equals(s4): true
2)如果比較的是非字符型變量,equals比較的是內(nèi)存的首地址值浮声,此時(shí)和"=="是一樣的虚婿,既比較兩邊指向的是不是同一個(gè)對(duì)象
Person p1 = new Person("xiaomi", 8);
Person p2 = new Person("xiaomi", 8);
System.out.println("p1.equals(p2): "+p1.equals(p2));
public static class Person{
? ? String name;
? ? int age;
? ? public Person(String name, int age){}
}
結(jié)果:
p1.equals(p2): false
二、equals和hashCode的區(qū)別
在java中任何一個(gè)對(duì)象都具有equals和hashCode兩種方法泳挥,因?yàn)樗鼈兌际窃贠bject類中定義的然痊,equals用來(lái)判斷兩個(gè)對(duì)象是否相同,如果相同則返回true羡洁,如果不相同則返回false玷过。hashCode則是返回一個(gè)int數(shù)值,在Object類中的默認(rèn)實(shí)現(xiàn)是“將該對(duì)象的內(nèi)部地址轉(zhuǎn)換成一個(gè)整數(shù)返回”。
官方說(shuō)明:
在 Java 應(yīng)用程序執(zhí)行期間辛蚊,在同一對(duì)象上多次調(diào)用 hashCode 方法時(shí)粤蝎,必須一致地返回相同的整數(shù),前提是對(duì)象上 equals 比較中所用的信息沒(méi)有被修改袋马。從某一應(yīng)用程序的一次執(zhí)行到同一應(yīng)用程序的另一次執(zhí)行初澎,該整數(shù)無(wú)需保持一致。?
如果根據(jù) equals(Object) 方法虑凛,兩個(gè)對(duì)象是相等的碑宴,那么在兩個(gè)對(duì)象中的每個(gè)對(duì)象上調(diào)用 hashCode 方法都必須生成相同的整數(shù)結(jié)果。?
以下情況不 是必需的:如果根據(jù) equals(java.lang.Object) 方法桑谍,兩個(gè)對(duì)象不相等延柠,那么在兩個(gè)對(duì)象中的任一對(duì)象上調(diào)用 hashCode 方法必定會(huì)生成不同的整數(shù)結(jié)果。但是锣披,程序員應(yīng)該知道贞间,為不相等的對(duì)象生成不同整數(shù)結(jié)果可以提高哈希表的性能。?
實(shí)際上雹仿,由 Object 類定義的 hashCode 方法確實(shí)會(huì)針對(duì)不同的對(duì)象返回不同的整數(shù)增热。(這一般是通過(guò)將該對(duì)象的內(nèi)部地址轉(zhuǎn)換成一個(gè)整數(shù)來(lái)實(shí)現(xiàn)的,但是 JavaTM 編程語(yǔ)言不需要這種實(shí)現(xiàn)技巧胧辽。)?
當(dāng)equals方法被重寫時(shí)峻仇,通常有必要重寫 hashCode 方法,以維護(hù) hashCode 方法的常規(guī)協(xié)定邑商,該協(xié)定聲明相等對(duì)象必須具有相等的哈希碼摄咆。
如果之重寫了equals或者h(yuǎn)ashCode方法而沒(méi)有重寫另外一個(gè)方法,可能會(huì)導(dǎo)致數(shù)據(jù)缺失
一之重寫equal為例奠骄,重寫hanshCode類似
public class HashCodeTest {
? ? public static void main(String [] args){
? ? ? ? HashSet set = new HashSet();
? ? ? ? Point p1 = new Point(1,1);
? ? ? ? Point p2 = new Point(1,1);
? ? ? ? System.out.println(p1.equals(p2));
? ? ? ? set.add(p1);
? ? ? ? set.add(p2);
? ? ? ? set.add(p1);
? ? ? ? Iterator iterator = set.iterator();
? ? ? ? while (iterator.hasNext()){
? ? ? ? ? ? Object o = iterator.next();
? ? ? ? ? ? System.out.println(o);
? ? ? ? }
? ? }
? ? public static class Point{
? ? ? ? int x;
? ? ? ? int y;
? ? ? ? public Point(int x, int y){
? ? ? ? ? ? super();
? ? ? ? ? ? this.x = x;
? ? ? ? ? ? this.y = y;
? ? ? ? }
? ? ? ? @Override
? ? ? ? public boolean equals(Object o) {
? ? ? ? ? ? if (this == o){
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? } else if (o == null){
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? } else if (getClass()? != o.getClass()){
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? }
? ? ? ? ? ? Point p = (Point) o;
? ? ? ? ? ? if (x != p.x || y != p.y){
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? }
? ? ? ? ? ? return super.equals(o);
? ? ? ? }
? ? ? ? @Override
? ? ? ? public String toString() {
? ? ? ? ? ? return "x: "+x+" , y: "+y;
? ? ? ? }
? ? }
}
輸出:
false
x: 1 , y: 1
x: 1 , y: 1
總結(jié):
1.hashCode是為了提高散結(jié)構(gòu)存儲(chǔ)中查找的效率豆同,在線性表表中沒(méi)有作用
2.若要重寫,equals和hashCode需要同時(shí)覆蓋
3.若equals為true含鳞,則hashCode一定相等
4.若equal返回值為false影锈,hashCode不一定不相等
5.如hashCode相等,equals不一定為true
6.若hashCode不相等蝉绷,則equals一定不相等
7.同一對(duì)象在執(zhí)行期間若已經(jīng)存儲(chǔ)在集合中鸭廷,則不能修改影響hashCode值的相關(guān)信息,否則會(huì)導(dǎo)致內(nèi)存泄露熔吗。