哈希表 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 以用作地图中的值,并为其覆盖 equals
和 hashcode
。
已解决
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;
}
}
我有一个巨大的浮点数组,我必须从中删除重复项。我试图创建一个 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 以用作地图中的值,并为其覆盖 equals
和 hashcode
。
已解决
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;
}
}