哈希表 containsValue 无法正常工作

HashTable containsValue not working properly

我有一个巨大的浮点数组,我必须从中删除重复项。我试图创建一个 HashTable 来填充唯一值并将其传递回另一个数组并 return 它。问题出在 containsValue 方法中,它总是 returns false,因此所有点都添加到哈希表中。

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;
}

非常感谢您的帮助。

h.containsValue(pt) 在查找匹配时比较数组的地址,而不是它们的内容。

要实现您想要的效果,您可以编写一个包装器 class 以用作地图中的值,并为其覆盖 equalshashcode

已解决

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;
    }
}