Reputation: 59
I have a huge float array and I have to remove duplicates from it. I tried to create an HashTable to populate with unique values and pass it back to another array and return it. The problem is in containsValue method, which always returns false, so all points are added in the HashTable.
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;
}
I really appreciate ay help.
Upvotes: 0
Views: 192
Reputation: 59
Solved
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;
}
Wrapper
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;
}
}
Upvotes: 0
Reputation: 1386
h.containsValue(pt)
compares the addresses of the arrays, not their contents, when looking for a match.
To achieve what you want, you can write a wrapper class to be used as values in the map, and override equals
and hashcode
for it.
Upvotes: 2