1.hashcode是用來查找的,如果你學過數據結構就應該知道,在查找和排序這一章有
例如內存中有這樣的位置
0 1 2 3 4 5 6 7
而我有個類,這個類有個字段叫ID,我要把這個類存放在以上8個位置之一,如果不用hashcode而任意存放,那么當查找時就需要到這八個位置里挨個去找,或者用二分法一類的算法。
但如果用hashcode那就會使效率提高很多。
我們這個類中有個字段叫ID,那么我們就定義我們的hashcode為ID%8,然后把我們的類存放在取得得余數那個位置。比如我們的ID為9,9除8的余數為1,那么我們就把該類存在1這個位置,如果ID是13,求得的余數是5,那么我們就把該類放在5這個位置。這樣,以后在查找該類時就可以通過ID除8求余數直接找到存放的位置了。

2.但是如果兩個類有相同的hashcode怎么辦那(我們假設上面的類的ID不是唯一的),例如9除以8和17除以8的余數都是1,那么這是不是合法的,回答是:可以這樣。那么如何判斷呢?在這個時候就需要定義 equals了。
也就是說,我們先通過 hashcode來判斷兩個類是否存放某個桶里,但這個桶里可能有很多類,那么我們就需要再通過 equals 來在這個桶里找到我們要的類。
那么。重寫了equals(),為什么還要重寫hashCode()呢?
想想,你要在一個桶里找東西,你必須先要找到這個桶啊,你不通過重寫hashcode()來找到桶,光重寫equals()有什么用啊
3。你要對A類排序,有兩種方法,一種就是讓A類實現comparabole結構并實現compareTo()方法,那么可以通過Collections.sort(List <A> list)對其進行排序
另一種方法:自己定義一個類B實現Comparator類并實現compare方法,
然后通過Collections.sort(List <A> list,B b)進行排序

hashCode()是用來產生哈希瑪的,而哈希瑪是用來在散列存儲結構中確定對象的存儲地址的,(這一段在 Java編程思想 中講的很清楚的)象util包中的 帶 hash 的集合類都是用這種存儲結構 :HashMap,HashSet, 他們在將對象存儲時(嚴格說是對象引用),需要確定他們的地址吧, 而HashCode()就是這個用途的,一般都需要重新定義它的,因為默認情況下,由 Object 類定義的 hashCode 方法會針對不同的對象返回不同的整數,這一般是通過將該對象的內部地址轉換成一個整數來實現的,現在舉個例子來說, 就拿HashSet來說 ,在將對象存入其中時,通過被存入對象的 hashCode() 來確定對象在 HashSet 中的存儲地址,通過equals()來確定存入的對象是否重復,hashCode() ,equals()都需要自己重新定義,因為hashCode()默認前面已經說啦,而equals() 默認是比較的對象引用,你現在想一下,如果你不定義equals()的話,那么同一個類產生的兩個內容完全相同的對象都可以存入Set,因為他們是通過equals()來確定的,這樣就使得HashSet 失去了他的意義,看一下下面這個:
import java.util.*;
/**
*類說明
* @author shellfeng E-mail:lsf830804@yahoo.com.cn
* @version 1.0
*
*/
public class Test {
public static void main(String[] args) {
HashSet set = new HashSet();
for (int i = 0; i <= 3; i++){
set.add(new Demo1(i,i));
}
System.out.println(set);
set.add(new Demo1(1,1));
System.out.println(set);
System.out.println(set.contains(new Demo1(0,0)));
System.out.println(set.add(new Demo1(1,1)));
System.out.println(set.add(new Demo1(4,4)));
System.out.println(set);
}

private static class Demo1 {
private int value;

private int id;

public Demo1(int value,int id) {
this.value = value;
this.id=id;
}

public String toString() {
return " value = " + value;
}

public boolean equals(Object o) {
Demo1 a = (Demo1) o;
return (a.value == value) ? true : false;
}

public int hashCode() {
return id;
}
}
}
你分別注釋掉hashCode()和 equals()來比較一下他們作用就可以拉,關鍵要自己動手看看比較的結果你就可以記得很清楚啦

如果還不是很明確可以再看另一個例子:
import java.util.HashMap;
import java.util.Map;

/**
*
* 類說明
*
* @author shellfeng E-mail:lsf830804@yahoo.com.cn
* @version 1.0
*/
public final class Test {

public static void main(String[] args) {
Map m = new HashMap();
m.put(new PhoneNumber(020, 12345678), "shellfeng");
System.out.println(m.get(new PhoneNumber(020, 12345678)));
}

private static class PhoneNumber {
/**
* 區號
*/
private short areaCode;

/**
* 擴展號
*/
private short extension;

public PhoneNumber(int areaCode, int extension) {
this.areaCode = (short) areaCode;
this.extension = (short) extension;
}

public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof PhoneNumber)) {
return false;
}
PhoneNumber pn = (PhoneNumber) o;
return pn.extension == extension && pn.areaCode == areaCode;
}

/**
* @see java.lang.Object#hashCode()
* @return result就是我們得到的散列值,其實我們的計算過程可以多種,這里只不過是一個例子,需要你的靈活運用,使其接近你需要的理想結果
*/
public int hashCode() {
int result = 17;
result = 37 * result + areaCode;
result = 37 * result + extension;
return result;
}
}
}

還是那句話:你注釋掉hashCode()比較一下他們作用就可以拉,關鍵要自己動手看看比較的結果你就可以記得很清楚啦

總結
hashCode()方法使用來提高Map里面的搜索效率的,Map會根據不同的hashCode()來放在不同的桶里面,Map在搜索一個對象的時候先通過hashCode()找到相應的桶,然后再根據equals()方法找到相應的對象.要正確的實現Map里面查找元素必須滿足一下兩個條件:
(1)當obj1.equals(obj2)為true時obj1.hashCode() == obj2.hashCode()必須為true
(2)當obj1.hashCode() == obj2.hashCode()為false時obj.equals(obj2)必須為false

Java中的集合(Collection)有兩類,一類是List,再有一類是Set。你知道它們的區別嗎?前者集合內的元素是有序的,元素可以重復;后者元素無序,但元素不可重復。
那么這里就有一個比較嚴重的問題了:要想保證元素不重復,可兩個元素是否重復應該依據什么來判斷呢?這就是Object.equals方法了。
但是,如果每增加一個元素就檢查一次,那么當元素很多時,后添加到集合中的元素比較的次數就非常多了。
也就是說,如果集合中現在已經有1000個元素,那么第1001個元素加入集合時,它就要調用1000次equals方法。這顯然會大大降低效率。
哈希算法也稱為散列算法,是將數據依特定算法直接指定到一個地址上。我們可以認為hashCode方法返回的就是對象存儲的物理地址(實際可能并不是,例如:通過獲取對象的物理地址然后除以8再求余,余數幾是計算得到的散列值,我們就認為返回一個不是物理地址的數值,而是一個可以映射到物理地址的值)。
這樣一來,當集合要添加新的元素時,先調用這個元素的hashCode方法,就一下子能定位到它應該放置的物理位置上。如果這個位置上沒有元素,它就可以直接存儲在這個位置上,不用再進行任何比較了;如果這個位置上已經有元素了,就調用它的equals方法與新元素進行比較,相同的話就不存了,不相同就散列其它的地址。所以這里存在一個沖突解決的問題。這樣一來實際調用equals方法的次數就大大降低了,幾乎只需要一兩次。

上面只是我個人的一下理解,有不當之處請大家指教