(CompareTo, Compare,hashCode,equals函數)持有對象與公有比較函數

(CompareTo, Compare,hashCode,equals函數)持有對象與公有比較函數

(一),   int CompareTo(Object o)的介紹

 

 

此函數沒有缺省值,必須自己定義它。表示調用此函數的對象與傳入的另一個對象o做比較,若返回負值(表示此對象小於傳入的對象,事實並沒有所謂的大小之分)則在數組或容器中將此對象放在傳入的對象前面,若返回正值則所放的位置相反,若返回0則不改變位置。

                       

(二):數組的排序和找查

 

 

(二.一)  對數組進行排序時系統自動調用int CompareTo(Object o)函數的情況

 

 

a是一個儲存對象的數組,Aa的一元素;

         當使用函數Arrays.sort(a);來爲a排序時,系統就會調用a[0]intCompareTo(Object o)函數,並且逐一a[1],a2],a[3]直至a[a.length-1]作爲參數輸入。因此a[0]調用int CompareTo(Object o)的次數是a.length-1

同理,a[1]也會以a[2],a3],a[4] 直至a[a.length-1]作爲參數調用a[1]int CompareTo(Object o)函數。同理,a[1]調用int CompareTo(Object o)的次數是a.length-2。依次類推。當然a[1]a[2]和其他元素調用int CompareTo(Object o)函數是交叉進行的。

 

 

(二.二)  對數組進行排序時對數組元素的要求

        

系統會將數組的元素向上轉型至Compararable, 然後用轉型後的對象調用int CompareTo(Object o)。因此數組內的所有元素所在的類必須實現接口Compararable並且複寫int CompareTo(Object o),因此數組也不能有空元素。

                       

(二.三)  對數組元素進行找查時系統自動調用int CompareTo(Object o)函數的情況

 

 

當使用函數Arrays.binarySearch(a,A);來找查數組a是否存在元素A時,則系統會以A爲參數逐一調用從a[0]開始至a[a..length-1]int CompareTo(Object o)函數,當然若找到A就不再調用。

 

 

(二.四)  對數組進行找查時對數組元素的要求

數組的元素的int CompareTo(Object o)函數必須能夠有效地起到比較作用,才能保證能找到目標。比如,每個元素的int CompareTo(Object o)不管任何情況都返回正值的話,那麼根據函數Arrays.binarySearch(a,A)自動調用函數int CompareTo(Object o)的流程,可知最終將發生邏輯矛盾(因爲,至少,一定會以元素本身作爲參數調用本身的int CompareTo(Object o)函數),發生邏輯矛盾就不可能找到目標。

 

 

(二.五)  對數組元素進行找查後的結果

設有三個相同的元素,a[11]=A1,a[12]=A2,a[13]=A3。找查A1時可以得出它的位置是11,找查A2A3同理得出它的位置是11,因爲比較函數int CompareTo(Object o) 相同,輸入的參數也相同。所以找查得出的位置的後面纔可能有相同元素,前面不可能有相同元素。

 

 

(二.六)  注意int compareTo(Object o)函數內是否有轉型動作

int CompareTo(Object o)函數裏面通常有轉型動作,把o轉型。因此數組中如果有多種對象元素且int CompareTo(Object o)函數裏面有轉型動作就不能用Arrays.sort(Object[] a)Arrays.binarySearch(Object[] a, Object key)來排序和找查,否則將發生執行期錯誤。要使用函數 sort(Object [] a,Comparato c)Arrays.binarySearch (Object[] a, Object key, Comparato c)。利用函數int compare(Object o1, Object o2)進行元素的排序和找查。

 

 

(二.七),   int compare(Object o1, Object o2)的介紹

 

 

此函數沒有缺省值,必須自己定義它。調用此函數的對象並不做比較,把傳入的兩個對象o1o2做比較,若返回負值(表示此o1小於o2,事實並沒有所謂的大小之分)則在數組或容器中把o1放在o2的前面,若返回正值則所放的位置相反,若返回0則不改變位置。

 

 

(二.八)  對數組進行排序時系統自動調用int compare(Object o1, Object o2)函數的情況

 

 

當使用函數sort(Object [] a,Comparato c);來爲a排序時系統就會調用ccompare(Object o1, Object o2)函數,並且逐一以(a[0],a[1], a[0],a[2])直至(a[0],a[a.length-1])作爲參數輸入。a[0] 作爲參數的次數是a.length-1

同理,c會以(a[1],a[2], a[1],a[2])直至(a[1],a[a.length-1])作爲參數調用compare(Object o1, Object o2)函數。同理,a[1] 作爲參數的次數是a.length-2。依次類推。當然以a[0]a[1]和其他元素作爲第一個參數調用ccompare(Object o1, Object o2)函數是交叉進行的。

 

 

(二.九)  對數組進行找查時對數組元素的要求

        

因爲比較函數是由對象c提供的,因此數組排序時數組內可以有空元素,可以不復寫int CompareTo(Object o)函數的元素,有可以有不同的元素,可以是任何對象元素。對數組元素沒有任何要求。當然,ccompare(Object o1, Object o2)函數不能對o1,o2進行轉型。

 

 

(二.十)  對數組元素進行找查時系統自動調用int compare(Object o1, Object o2)函數的情況

 

 

Arrays.binarySearch ( a, A, c);來找查數組a是否存在元素A時,則系統會以A爲第二個參數分別以a[0]a[a..length-1] 爲第一個參數逐一調用ccompare(Object o1, Object o2)函數。當然若找到A就不再調用。

 

 

(二.十一)  對數組進行找查時對數組元素的要求與結果

要求:當然,ccompare(Object o1, Object o2)函數和int CompareTo(Object o)函數一樣,必須提供有效的比較方式,才能保證找到目標。

 

 

結果:設有三個相同的元素,a[11]=A1,a[12]=A2,a[13]=A3。找查A1時可以得出它的位置是11,找查A2A3同理得出它的位置是11,因爲比較函數compare(Object o1, Object o2)相同,輸入的參數也相同。所以找查得出的位置的後面纔可能有相同元素,前面不可能有相同元素。

 

 

(三):List排序和找查

CollectionsArrays一樣,Arrays爲數組提供一些操作函數,Collections就爲ListSet提供一些操作函數。但Collections只爲List提供元素的排序和找查,因爲Set並不需要。

在不排序的情況下,第一加入的元素對應的序列號爲0,第二加入的元素對應的序列號爲1,依次類推。

                       

對它排序可以使用函數Collections.sort(List list), Collections.sort(List list,Comparato c)

                       

       對它的元素進行找查可以使用函數Collections.binarySearch (List list,Object key), Collections.binarySearch (List list,Object key,Comparato c)

 

 

       sortbinarySearchList排序和找查和用sortbinarySearch對數組進行排序和找查,程序的要求,過程,結果,完全一模一樣。

 

 

()TreeSet加入對象

      

       intCompareTo(Object o)函數不僅用來確定TreeSet元素的次序,而且用來確定TreeSet元素的獨一無二。

                        TreeSet的一個對象tS,tS.add(Object o),加入對象時,系統就會調用加入的對象ointCompareTo(Object o)函數,並且沒有次序地把已經加入的對象作爲參數輸入。直到確定tS裏面元素的次序,然後停止調用ointCompareTo(Object o)函數。若intCompareTo(Object o)函數返回0值,則不將對象o加入,而不是用o來代替與o相同的對象。  

       也就是說TreeSet加入對象後,TreeSet裏面元素的唯一性和元素的次序就得到了確定。

 

 

()TreeMap加入對象與取出對象

       intCompareTo(Object o)函數不僅用來確定TreeMapkey值次序,而且用來確定key值的獨一無二。

                       

TreeMap的一個對象tM,tM.put(Object key,Object value),加入對象時,系統就會調用keyintCompareTo(Object o)函數,並且沒有次序地把已經加入的鍵值對象作爲參數輸入。直到確定tM裏面鍵值對象的次序,然後停止調用keyintCompareTo(Object o)函數。若intCompareTo(Object o)函數返回0值,則將key加入並且加入它對應的value值,代替覆蓋與key相同的鍵值對象和用value值代替它的實值。  

      

tM.get(Object key)來取它對應的實值時,系統也會調用keyintCompareTo(Object o)函數,並且沒有次序地把已經加入的鍵值對象作爲參數輸入,用來找查和確定是否有鍵值和這個key對應,有則調用對應這個key的鍵值的實值。  

 

 

()int hashCode()函數的介紹

int hashCode()函數存在每一個類中,表示根據它的返回值產生一個int型整數(即hash code)來代表這個對象。在缺省的狀態下,int hashCode()函數會爲每一個對象產生一個無二的hash code。若複寫int hash code()函數,則系統會根據它的返回值來產生hash code代表對象,不同的的返回值會得到不同的hash code,相同的的返回值會得到相同的hash code不論是否在同一個包中或其他情況,返回值相同hash code則相同,但注意返回值與所得到的hash code的值是不相同的。

 

 

()int hashCode()函數的與Stirng toString()函數的關係

當對象轉化爲字符串時,即用字符串的形式表示對象時(注意不是把它轉型成String),系統會先自動調用此對象的String  toString()函數。缺省的String  toString()函數會用“包名+類名+@+hash code”的字符串來代表調用它的對象。所以,設hC是一個對象的話,象這樣的動作:String s=""+hC; System.out.println(hC); 系統都會自動先調用hCString  toString()函數,後再調用hCint hashCode()函數,因爲要獲取hChash code 它的String  toString()函數裏面會調用hCint hashCode()函數。即缺省的String  toString()函數會調用hCint hashCode()函數。若複寫了String  toString()函數,當對象轉化爲字符串時,就不一定會調用int hashCode()函數了。

 

 

()boolean equals(Object obj)函數的介紹

        boolean equals(Object obj)函數存在每一個類中,它表示調用此函數的對象與傳入的對象obj做比較,若返回true(就說這兩個對象相等,事實上除了它本身沒有一個對象和它真正相等)則容器就把這兩個對象當作同一元素對待。若返回false,則容器就認爲這兩個對象是兩個不同的元素。在缺省的狀態下,boolean equals(Object obj)函數除了把調用它的對象作爲參數輸入會返回true,否則使用其他對象作爲參數都會返回false

 

 

()HashSet加入對象

1),HashSet的一個對象hS,hS.add(Object o),加入對象時,由於要確定每個元素的唯一性,系統就會首先自動調用對象oint hashCode()函數。

2),然後會把得到的ohash code值與已經加入容器的對象的hash code值做比較(注意:比較的只是hash code值而不是對象的字符串表達式的比較,而且這一過程看不見)。如果將要加入對象ohash code值與已經加入的容器裏面的任意一個對象的hash code值不同,則將對象o加入容器。

3),如果有對象的hash code值與ohash code值相同,則系統會再自動調用0boolean equals(Object obj)函數,並且按對象加入容器的次序的相反順序(即後加入的先作參數)逐一把所有這些與對象ohash code值相同的對象作爲參數,來進行比較。

4),如果oboolean equals(Object obj)函數的所有返回值都是false則將對象o加入容器。

      如果返回值出現true,則將對象o代替這時作爲boolean equals(Object obj)的參數的對象加入容器,即用o覆蓋這時的參數obj。然後終止調用oboolean equals(Object obj)函數。

      如果這些參數中,含有對象o本身,則在對象o作爲自己的函數的參數開始調用本身的boolean equals(Object obj)函數時,系統會自動終止oboolean equals(Object obj)函數的調用,然後不把對象o再次加入容器。

5,即hS.add(Object o),加入對象時,要調用boolean equals(Object obj)函數的條件是: hash code值不相同和參數不能爲本身。

 

 

()HashMap加入對象與取出對象

1HashMap加入對象

1.1),HashMap的一個對象hM, hM.put(Object key,Object value),加入對象時,由於要確定每個key值的唯一性,系統就會首先自動調用對象keyint hashCode()函數。

1.2),然後會把得到的對象keyhash code值與已經加入容器的鍵值對象的hash code值做比較(注意:比較的只是hash code值而不是對象的字符串表達式的比較,而且這一過程看不見)。如果將要加入對象keyhash code值與已經加入的容器裏面的任意一個鍵值對象的hash code值不同,則將對象keyvalue加入容器。

1.3),如果有鍵值對象的hash code值與keyhash code值相同,則系統會再自動調用keyboolean equals(Object obj)函數,並且按對象加入容器的次序的相反順序(即後加入的先作參數)逐一把所有這些與對象keyhash code值相同的鍵值對象作爲參數,來進行比較。

1.4),如果keyboolean equals(Object obj)函數的所有返回值都是false則將對象keyvalue加入容器。

      如果返回值出現true,則將對象key代替這時作爲boolean equals(Object obj)的參數的鍵值對象加入容器,即用key覆蓋這時的參數obj,然後用key對應的實值value覆蓋此時的obj對應的實值。最後終止調用keyboolean equals(Object obj)函數。

      如果這些參數中,含有對象key本身,則在對象key作爲自己的函數的參數開始調用本身的boolean equals(Object obj)函數時,系統會自動終止oboolean equals(Object obj)函數的調用,然後鍵值保持不變用新實值覆蓋舊覆蓋。

1.5,即hM.put(Object key,Object value),加入對象時,要調用boolean equals(Object obj)函數的條件是: hash code值不相同和參數不能爲本身。

 

 

2HashMap取出對象

2.1),HashMap的一個對象hM, hM.get(Object key)來取它對應的實值時,由於要確定容器內是否有鍵值和這個key對應,,系統就會首先自動調用對象keyint hashCode()函數。

2.2),然後會把得到的對象keyhash code值與已經加入容器的鍵值對象的hash code值做比較(注意:比較的只是hash code值而不是對象的字符串表達式的比較,而且這一過程看不見)。如果對象keyhash code值與已經加入的容器裏面的任意一個鍵值對象的hash code值不同,則容器內沒有與key對應的鍵值,取出的值是null

2.3),如果有鍵值對象的hash code值與keyhash code值相同,則系統會再自動調用keyboolean equals(Object obj)函數,並且按對象加入容器的次序的相反順序(即後加入的先作參數)逐一把所有這些與對象keyhash code值相同的鍵值對象作爲參數,來進行比較。

2.4),如果keyboolean equals(Object obj)函數的所有返回值都是false則容器內沒有與key對應的鍵值,取出的值是null。。

      

如果返回值出現true,則取出此時作爲boolean equals(Object obj)的參數的鍵值對象所對應的實值。然後終止調用keyboolean equals(Object obj)函數。

      

如果這些參數中,含有對象key本身,則在對象key作爲自己的函數的參數開始調用本身的boolean equals(Object obj)函數時,系統會自動終止keyboolean equals(Object obj)函數的調用,並取出key對應的實值。

2.5, 要調用boolean equals(Object obj)函數的條件是: hash code值不相同和參數不能爲本身。

 

 

        最後:知道這些過程就能有效的定義這些函數了。哈哈!

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章