2016-02-23 45 views
0

我有一個巨大的浮點數組,我必須從中刪除重複項。我試圖創建一個HashTable來填充唯一值並將其傳遞迴另一個數組並將其返回。問題在於containsValue方法,它始終返回false,因此所有點都添加到HashTable中。HashTable containsValue無法正常工作

private float[] removeDuplicates1(float[] input){ 
    Hashtable<Integer, float[]> h= new Hashtable<>(); 
    for(int i=0; i<input.length/3; ++i) { 
     float[] pt= new float[]{input[i * 3], input[i * 3 + 1], input[i * 3 + 2]}; 
     Log.i(TAG, Float.toString(pt[0]) + " " +Float.toString(pt[1]) + " " +Float.toString(pt[2])); //ok 
     Log.i(TAG, Boolean.toString(h.containsValue(pt)));  //always false !? 
     if(!(h.containsValue(pt))){ 
      h.put(i,pt); 
      Log.i(TAG, "added"); 
     } 
     else Log.i(TAG, "NOT added"); 
    } 
    float[] whitelist = new float[h.size()*3]; 
    int a=0; 
    for(int j=0; j<h.size(); j++){ 
     float[] f= h.get(j); 
     whitelist[a]= f[0]; 
     whitelist[a+1]= f[1]; 
     whitelist[a+2]= f[2]; 
     a=a+3; 
    } 
    return whitelist; 
} 

我真的很感謝你的幫助。

+3

你問一個陣列是否等於另一個,基本上是這樣。那是*永遠不會變成真 - 數組不會覆蓋'equals'。它看起來像你的輸入實際上是一個三元組的集合 - 聽起來你應該用三個「float」字段構造一個類(我們不能真正說出它們的含義),它恰當地覆蓋了'equals'。還要注意''Hashtable.containsValue'基本上是一個O(n)查找 - 這是一個非常糟糕的選擇去重複數據。 –

+0

containsValue使用equals方法進行比較,兩個數組永遠不會相等。 –

+0

不要忘記重寫'hashCode()',因爲你想使用一個HashTable,它只會比較具有相同哈希碼的對象。在你的情況下,最簡單的hashCode就是arry的長度。 – ctst

回答

2

h.containsValue(pt)尋找匹配時,比較陣列,而不是其內容的地址。

要實現您想要的功能,您可以編寫一個包裝類,以用作地圖中的值,並覆蓋它的equalshashcode

+0

好吧,我明白我必須爲float [] Point做一個包裝器對象類,但我不明白什麼是hashcode,它是如何工作的。你能舉個例子嗎? –

+0

的'hashcode'合同類Object中的Javadoc中所述: https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode() 的接觸部分是:「•如果兩個對象根據equals(Object)方法相等,那麼對這兩個對象的每一個調用hashCode方法必須產生相同的整數結果」,這就是爲什麼當您覆蓋equals時應該總是覆蓋它的原因'。 Eclipse有一個基於類的成員生成兩者的選項。 –

0

解決

private float[] removeDuplicates1(float[] input){ 
    Hashtable<Integer, Point> h= new Hashtable<>(); 
    int hn=0; 
    for(int i=0; i<input.length/3; ++i) { 
     Point pt= new Point(input[i * 3], input[i * 3 + 1], input[i * 3 + 2]); 
     Log.i(TAG, Float.toString(pt.x) + " " +Float.toString(pt.y) + " " +Float.toString(pt.z)); 
     Log.i(TAG, Boolean.toString(h.containsValue(pt))); 
     if(!(h.containsValue(pt))){ 
      h.put(hn,pt); 
      hn++; 
      Log.i(TAG, "added"); 
     } 
     else Log.i(TAG, "NOT added"); 
    } 
    float[] whitelist = new float[h.size()*3]; 
    int a=0; 
    for(int j=0; j<h.size(); ++j){ 
     Point p = new Point(h.get(j)); 
     whitelist[a] = p.x; 
     whitelist[a + 1] = p.y; 
     whitelist[a + 2] = p.z; 
     a = a + 3; 
    } 
    return whitelist; 
} 

包裝

public class Point { 
    public float x; 
    public float y; 
    public float z; 

    public Point(float x, float y, float z){ 
     this.x=x; 
     this.y=y; 
     this.z=z; 
    } 

    public Point(Point p){ 
     this.x=p.x; 
     this.y=p.y; 
     this.z=p.z; 
    } 

    @Override 
    public boolean equals(Object o){ 
     final Point p = (Point) o; 
     if((p.x==this.x) && (p.y==this.y) && (p.z==this.z)) return true; 
     else return false; 
    } 

    @Override 
    public int hashCode() { 
     int hash = 3; 
     hash = 53 * hash + Float.floatToIntBits(this.x); 
     hash = 53 * hash + Float.floatToIntBits(this.y); 
     hash = 53 * hash + Float.floatToIntBits(this.z); 
     return hash; 
    } 
}