為什么重寫equals()就必須重寫hashCode(),什么情況下可以不重寫hashCode()


  (1)當所在類不使用HashSet、Hashtable、HashMap等散列集合進行存儲的時候,可以不使用hashcode。

  (2)當在HashSet、Hashtable、HashMap中使用該類時,hashcode和equals是有關系的,hashcode和equals需要同時重寫才能保證元素的唯一性。hashcode是為了提高散列結構存儲中查找的效率,在線性表中沒有作用。

  ==操作符比較的是值【變量(棧)內存中存放的對象的(堆)內存地址】。

  equal用於比較兩個對象的值是否相同【不是比地址】。

  注意:Object類中的equals方法和“==”是一樣的,沒有區別,而String類,Integer類等一些類,是重寫了equals方法,才使得equals和“==不同”。對於基礎數據類型來說,沒有重寫equals方法,故兩者是一樣。

①equals()方法:

public class BaseTypeDemo {
    public static void main(String[] args) {
        //對於基本類型的變量。"=="和"equal"的區別
        int t1=57;
        int t2=67;
        int t3=124;
        int t4=124;
        //“==”對於基本數據類型,判斷兩個變量的值是否相等。
        Boolean result1=(t1==t2);
        Boolean result2=((t1+t2)==t3);
        Boolean result3=(t3==t4);
        System.out.println("【t1==t2】"+result1);
        System.out.println("【(t1+t2)=t3】"+result2 );
        System.out.println("【t3=t4】"+result3);
 
        //“equal”不能用於基本數據類型。只能用於類變量。對於基本數據類型要用其包裝類。
        Integer i1=new Integer(t1);
        Integer i2=new Integer(t2);
        Integer i3=new Integer(t3);
        Integer i4=new Integer(t4);
 
 
        Boolean ri1=i1.equals(i2);
        Boolean ri2=i3.equals(i1+i2);
        Boolean ri3=i3.equals(i4);
 
        System.out.println("【i1.equals(i2)】"+ri1);
        System.out.println("【i3.equals(i1+i2)】"+ri2);
        System.out.println("【i3.equals(i4)】"+ri3);
    }
}
/**
*運行結果
【t1==t2】false
【(t1+t2)=t3】true
【t3=t4】true
【i1.equals(i2)】false
【i3.equals(i1+i2)】true
【i3.equals(i4)】true
*/

  String類,是重寫了equals方法,才使得equals和“==不同”。讓equals比較的值,==比較的引用地址。

public class StringDemo {
    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = new String("Hello");
        String str3 = str2; // 引用傳遞
        System.out.println(str1 == str2); // false
        System.out.println(str1 == str3); // false
        System.out.println(str2 == str3); // true
        System.out.println(str1.equals(str2)); // true
        System.out.println(str1.equals(str3)); // true
        System.out.println(str2.equals(str3)); // true
    }
}

  重寫equals()方法時需要把類的字段的那些在實際對象中進行傳入比較,保證是比較的對象的“內容”。而如果不重寫此時的hashCode()的話,就會出現如果是相同的一個對象,但是我修改了這個對象的某個屬性,比如在hashMap中保存的這個對象,但是此時我再想get到它就只能返回一個空值null了,因為hash值是與對象的字段屬性相關聯的,此時由於修改了這些字段屬性,所以對應的對象的哈希值也發生了改變,再用此時的哈希值去取對象是取不到的。

  

package map.test;

import java.util.HashMap;
import java.util.Map;

public class Person {
	private String name;
	private int age;

	public Person() {
		super();
	}

	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	// 測試hashCode
//    @Override
//    public boolean equals(Object obj) {
//        // TODO Auto-generated method stub
//        return true;
//    }

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

	public static void main(String[] args) {
		Person p1 = new Person("tom", 18);
		Person p2 = new Person("jack", 19);
		Map map = new HashMap<>();
		map.put(p1, "111");
		map.put(p2, "2222");
		// key的字段發生了改變
		p1.setAge(5);
		System.out.println(map.get(p1));
		System.out.println(map.get(p2));
	}
}

  

 

   所以使用hashmap不能輕易地去修改key的字段值,但此時map中還是存在有三個元素,只不過用get(p1)此時只能獲取到被修改了過后的key對應的value值:但是可以看的出來p1引用都指向的是同一個對象

public static void main(String[] args) {
		Person p1 = new Person("tom", 18);
		Person p2 = new Person("jack", 19);
		Map map = new HashMap<>();
		map.put(p1, "111");
		map.put(p2, "2222");
		// key的字段發生了改變
		p1.setAge(5);
		map.put(p1, "333");
		System.out.println(map);
		System.out.println(map.size());
		System.out.println(map.get(p1));
		System.out.println(map.get(p2));
}

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM