Java 使用HashSet的对象的唯一列表
有人能告诉我我的代码有什么问题吗?我将代码从转换为使用字符串数组,而不是使用两个整数,其中我需要一个基于字符串数组第0个索引的唯一列表。问题是重写的equals函数从未被调用,因此我有重复的条目Java 使用HashSet的对象的唯一列表,java,hashset,Java,Hashset,有人能告诉我我的代码有什么问题吗?我将代码从转换为使用字符串数组,而不是使用两个整数,其中我需要一个基于字符串数组第0个索引的唯一列表。问题是重写的equals函数从未被调用,因此我有重复的条目 public static void main(String[] args) { class bin { String[] data; bin (String[] data)
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);
}
publicstaticvoidmain(字符串[]args)
{
分类箱
{
字符串[]数据;
bin(字符串[]数据)
{
这个。数据=数据;
}
@凌驾
公共布尔等于(对象me)
{
bin binMe=(bin)me;
if(this.data[0].equals(binMe.data[0]){return true;}
else{return false;}
}
@凌驾
公共int hashCode()
{
最终整数素数=31;
int结果=1;
result=prime*result+Arrays.hashCode(数据);
返回结果;
}
@凌驾
公共字符串toString()
{
返回数据[0]+“”+数据[1];
}
}
Set q=新的HashSet();
q、 添加(新bin(新字符串[]{“100”,“200”});
q、 添加(新bin(新字符串[]{“101”,“201”});
q、 添加(新bin(新字符串[]{“101”,“202”});
q、 添加(新bin(新字符串[]{“103”,“203”});
系统输出println(q);
}
给出输出:[101 202、100 200、101 201、103 203]如果要基于第一个元素进行比较,请不要获取完整数组的哈希代码
Arrays.hashCode(data);
使用
问题是被重写的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);
}
这是不正确的。确实有人打电话给它。但是,只有当equals
方法返回true且hashCode
返回相同的int时,两个set元素才被视为相等。在您的示例中,您已经重写了equals
方法,以基于字符串数组的第一个元素进行逻辑比较。但是,您需要确保hashCode还为您认为在逻辑上相等的两个元素返回相同的int
因此,在hashCode
实现中更新以下语句
从
result=prime*result+array.hashCode(数据)代码>
到
result=prime*result+data[0].hashCode()代码>哈希[设置/映射]的工作方式是使用哈希代码将项目分组到列表中,然后搜索这些列表,这意味着如果所有哈希代码都是唯一的,则列表仅为1个项目,并加快了项目的查找速度
如果hashCode指向错误的列表,则没有要检查相等性的项,因此永远不会调用equals方法,并且会添加每个项,而不仅仅是唯一的项
使用data[0].hashCode()代替对整个字符串数组计算hashCode根据@cricket_007的答案,由于散列码不同,因此从不调用Equals。你认为哪一个元素在这里被复制了?谢谢,我没有意识到这是在设置哈希代码时发生的事情,这是有效的。