2013-10-13 92 views
1

看起來像int []的hashCode()和equals()很差實現,或根本沒有實現! (使用Android進行測試,但我希望它適用於任何Java環境)。hashCode和equals在int []中的實現Java

爲了得到HashSet.contains()正常工作,我不得不創建INT []的包裝(PLSE,不要批評我的編碼風格,看本質):

public class IntArray { 
    private int[] value; 

    public IntArray(int[] value) { 
     this.value = value; 
    } 

    @Override 
    public int hashCode() { 
     int sum = 0; 
     // Integer overflows are cheerfully welcome. 
     for (int elem: value) sum += elem; 
     return sum; 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (o == null) return (value==null); 

     if (value != null) { 
      if (o instanceof int[]) 
       return compare((int[])o); 

      if (o instanceof IntArray) 
       return compare(((IntArray)o).value); 
     } 

     return false; 
    } 

    protected boolean compare(int[] other) { 
     int len = value.length; 
     if (other.length != len) return false; 
     for (int i=0; i<len ; i++) 
      if (value[i] != other[i]) return false; 
     return true; 
    } 
} 

工作正常,但我更喜歡避免自定義包裝或第三方庫。有沒有選擇?

+1

「* hashCode()和equals()for int []實施得不好,或根本沒有實現*」小心細化? –

+0

hashCode和equals對於數組本質上默認爲Object中的實現,它只會找到一個等於它自己的對象。這並不是「執行不力」,當然也不是「完全沒有實施」,而是按照定義實施。然而,你的情況並非如此,我們可以說,「滿意」是正確的。 –

+1

是不是'ArrayList '你正在尋找的包裝? –

回答

1

由於標準Java Hashtable不允許覆蓋用於密鑰的哈希碼,因此您運氣不佳,需要像使用包裝一樣使用包裝。

記住,你的hashCode的實現是非常糟糕的,你可以使用這個(從標準JDK java.util.Arrays中獲得),以獲得更好的哈希distrubtion:

public static int hashCode(int a[]) { 
    if (a == null) 
    return 0; 

    int result = 1; 
    for (int element : a) 
    result = 31 * result + element; 
    return result; 
} 

另一種方法是使用不同的Hashtable,它可以處理基元。 其中一個選項是Banana,這是我創建的原始集合庫。

+0

謝謝,實際上這種方法提供了散列值更零星的分佈。可能有31個用作素數,但爲了提高效率(尤其是Android),使用2的冪乘以左移而不是乘法可能會更好。 – cyanide

+0

是的,31是專門選擇的,因爲它是素數。兩班倒的力量可能會導致更糟糕的分佈,並且這不太可能會讓你失望。 –

0

在Omry Yadan的消息之後,hashCode函數變得如此簡單!

@Override 
    public int hashCode() { 
     return Arrays.hashCode(value); 
    } 

對於RISC CPU,如ARM,這可能是更有效的:

@Override 
    public int hashCode() { 
     int code = 0; 
     if (value != null) { 
      code++; 
      for (int elem: value) 
       code = (code<<5) - code + elem; 
     } 
     return code; 
    } 

可能還存在用於比較陣列)的標準功能,在這種情況下等於(也得以簡化?

+0

Arrays.asList(value).compareTo(Arrays.asList(other)) –

相關問題