HashSet不删除所有重复的条目

时间:2016-11-02 14:13:47

标签: java eclipse guava

我正在尝试使用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

使用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个我想要的条目。我希望任何与之前添加的条目具有相同权重或术语的新条目被视为重复。

感谢所有帮助!

马特

2 个答案:

答案 0 :(得分:11)

  

我希望任何与之前添加的条目具有相同权重或术语的新条目被视为重复。

这不是平等的运作方式。平等必须是传递 - 因此,如果x.equals(y)返回true,并且y.equals(z)返回true,则x.equals(z)必须返回true。

在你想要的关系中并非如此。

请注意,它目前还不是equals方法检查的内容:

return Objects.equal(this.weight, other.weight)
    && Objects.equal(this.theTerm, other.theTerm);

如果权重匹配,则仅返回true,这对于相等关系是正常的。这就是为什么你在你的集合中获得三个条目的原因 - 因为当以这种方式查看时,你有三个不同的内容。

从根本上说,HashSet以及所有其他涉及平等的集合都不会以简单的方式帮助您。您需要拥有三个独立的集合:

  • 一组权重
  • 一组条款
  • 一组(或列表)条目。

如果您考虑的条目在权重集中有一个权重,那么您应该跳过它 - 否则,您应该为每个条目添加一个条目三个系列中的。

答案 1 :(得分:6)

考虑hashCode课程中equals(和Term)的实施情况,您应该期待3个条目,对应于所涉及的对:

999990  bummer
99999   bummer
999990  bummerr

hashCodeequals评估该对的两个属性,即weight doubletheTerm String

该集合将通过比较哈希码来评估不等式,这对于上面列出的3个元素将是不同的。