有谁能告诉我我的代码存在什么问题?我将代码从this post转换为使用String数组而不是两个整数,其中我想要一个基于String数组的第0个索引的唯一列表。问题是被覆盖的equals函数永远不会被调用,因此我重复了一些条目。
public static void main(String[] args)
{
class bin
{
String[] data;
bin (String[] data)
{
this.data=data;
}
@Override
public boolean equals(Object me)
{
bin binMe = (bin)me;
if(this.data[0].equals(binMe.data[0])) { return true; }
else { return false; }
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + Arrays.hashCode(data);
return result;
}
@Override
public String toString()
{
return data[0] + " " + data[1];
}
}
Set<bin> q= new HashSet<bin>();
q.add(new bin(new String[]{"100", "200"}));
q.add(new bin(new String[]{"101", "201"}));
q.add(new bin(new String[]{"101", "202"}));
q.add(new bin(new String[]{"103", "203"}));
System.out.println(q);
}
输出:[101 202,100 200,101 201,103 203]
答案 0 :(得分:2)
如果您希望基于第一个元素进行比较,请不要使用完整数组的哈希码
Arrays.hashCode(data);
使用
data[0].hashCode();
答案 1 :(得分:2)
问题是被覆盖的equals函数永远不会得到 因此,我重复了参赛作品。
这是不正确的。它确实被调用了。但是,只有两个集合元素都被认为是相等的,equals
方法返回true,hashCode
返回相同的int。在您的情况下,您已经覆盖了equals
方法,以根据字符串数组的第一个元素进行逻辑比较。但是,您需要确保hashCode还为您认为在逻辑上相等的两个元素返回相同的int
。
因此,请在hashCode
实施
这
result = prime * result + Arrays.hashCode(data);
到
result = prime * result + data[0].hashCode();
答案 2 :(得分:1)
Hash [Set / Map]的工作方式是使用hashCode将项目分组到列表中,然后搜索这些列表,这意味着如果所有hashCodes都是唯一的,那么列表只是1个项目,它加快了项目的查找速度。
如果你的hashCode指向错误的列表,则没有项目要检查是否相等,所以从不调用equals方法,并且每个项目都被添加,而不仅仅是唯一的项目。
不是在整个字符串数组上计算hashCode,而是使用data[0].hashCode();
,根据@ cricket_007的答案