HashSet 没有删除所有重复的条目
HashSet not removing all duplicate entries
我正在尝试使用 HashSet 来确保我从 .txt 文件中读取的数据是唯一的。
下面是示例数据;
999990 bummer
999990 bummer
999990 bummer
999990 bummer
99999 bummer
999990 bummerr
使用 Java.io.File 和 Java.util.Scanner 读取并存储为术语对象;
阅读方面;
while (rawTerms.hasNextLine()){
String[] tokens = rawTerms.nextLine().trim().split(delimiter);
if (tokens.length == 2) {
uniqueSet.add(new Term(Double.parseDouble(tokens[0]), tokens[1])); //add the term to set
}
else {
rawTerms.close();
throw new Exception("Invalid member length: "+ tokens.length);
}
}
allTerms = new ArrayList<>(uniqueSet); //Covert set into an ArrayList
class 期使用 Guava;
public Term(double weight, String theTerm){
this.weight = weight;
this.theTerm = theTerm;
}
@Override
public boolean equals(final Object obj) {
if (obj instanceof Term){
final Term other = (Term) obj;
return Objects.equal(this.weight, other.weight)
&& Objects.equal(this.theTerm, other.theTerm);
}
else {
return false;
}
}
@Override
public String toString(){
return toStringHelper(this).addValue(weight)
.addValue(theTerm).toString();
}
@Override
public int hashCode() {
return Objects.hashCode(this.weight, this.theTerm);
}
但是,当我 运行 测试以检查存储条目的数组大小时,我得到了 3 个条目,而不是我想要的 1 个。我希望任何与之前添加的条目具有相同权重或期限的新条目都被视为重复条目。
感谢所有帮助!
马特
考虑到 hashCode
(和 equals
)在 Term
class 中的实施,您 应该 期望 3 个条目,对应涉及的对数:
999990 bummer
99999 bummer
999990 bummerr
hashCode
和 equals
都计算对的两个属性,即 weight
double
和 theTerm
String
。
该集合将通过比较哈希码来评估不平等性,这对于上面列出的 3 个元素来说是不同的。
I would like any new entry with either the same weight or term as previously added entries to be considered a duplicate.
这不是平等的运作方式。相等性必须 可传递 - 所以如果 x.equals(y)
return 为真,并且 y.equals(z)
return 为真,则 x.equals(z)
必须 return 为真。
你想要的关系不是这样。
请注意,这也不是您的 equals
方法目前检查的内容:
return Objects.equal(this.weight, other.weight)
&& Objects.equal(this.theTerm, other.theTerm);
如果权重 和 项匹配,则只有 return 为真,这对于等式关系是正常的。这就是为什么你的集合中有三个条目 - 因为当以这种方式查看时,你 do 有三个不同的实体。
从根本上说,HashSet
和所有其他处理平等的集合不会以简单的方式帮助您。您需要拥有三个独立的集合:
- 一组权重
- 一组术语
- 一组(或列表)条目。
如果您正在考虑的条目在权重集中有一个权重 或 在术语集中有一个术语,您应该跳过它 - 否则,您应该添加一个进入三个集合中的每一个。
我正在尝试使用 HashSet 来确保我从 .txt 文件中读取的数据是唯一的。
下面是示例数据;
999990 bummer
999990 bummer
999990 bummer
999990 bummer
99999 bummer
999990 bummerr
使用 Java.io.File 和 Java.util.Scanner 读取并存储为术语对象;
阅读方面;
while (rawTerms.hasNextLine()){
String[] tokens = rawTerms.nextLine().trim().split(delimiter);
if (tokens.length == 2) {
uniqueSet.add(new Term(Double.parseDouble(tokens[0]), tokens[1])); //add the term to set
}
else {
rawTerms.close();
throw new Exception("Invalid member length: "+ tokens.length);
}
}
allTerms = new ArrayList<>(uniqueSet); //Covert set into an ArrayList
class 期使用 Guava;
public Term(double weight, String theTerm){
this.weight = weight;
this.theTerm = theTerm;
}
@Override
public boolean equals(final Object obj) {
if (obj instanceof Term){
final Term other = (Term) obj;
return Objects.equal(this.weight, other.weight)
&& Objects.equal(this.theTerm, other.theTerm);
}
else {
return false;
}
}
@Override
public String toString(){
return toStringHelper(this).addValue(weight)
.addValue(theTerm).toString();
}
@Override
public int hashCode() {
return Objects.hashCode(this.weight, this.theTerm);
}
但是,当我 运行 测试以检查存储条目的数组大小时,我得到了 3 个条目,而不是我想要的 1 个。我希望任何与之前添加的条目具有相同权重或期限的新条目都被视为重复条目。
感谢所有帮助!
马特
考虑到 hashCode
(和 equals
)在 Term
class 中的实施,您 应该 期望 3 个条目,对应涉及的对数:
999990 bummer
99999 bummer
999990 bummerr
hashCode
和 equals
都计算对的两个属性,即 weight
double
和 theTerm
String
。
该集合将通过比较哈希码来评估不平等性,这对于上面列出的 3 个元素来说是不同的。
I would like any new entry with either the same weight or term as previously added entries to be considered a duplicate.
这不是平等的运作方式。相等性必须 可传递 - 所以如果 x.equals(y)
return 为真,并且 y.equals(z)
return 为真,则 x.equals(z)
必须 return 为真。
你想要的关系不是这样。
请注意,这也不是您的 equals
方法目前检查的内容:
return Objects.equal(this.weight, other.weight)
&& Objects.equal(this.theTerm, other.theTerm);
如果权重 和 项匹配,则只有 return 为真,这对于等式关系是正常的。这就是为什么你的集合中有三个条目 - 因为当以这种方式查看时,你 do 有三个不同的实体。
从根本上说,HashSet
和所有其他处理平等的集合不会以简单的方式帮助您。您需要拥有三个独立的集合:
- 一组权重
- 一组术语
- 一组(或列表)条目。
如果您正在考虑的条目在权重集中有一个权重 或 在术语集中有一个术语,您应该跳过它 - 否则,您应该添加一个进入三个集合中的每一个。