HashSet不删除所有重复的条目

Mat*_*ran 0 java eclipse guava

我试图使用HashSet来确保我从.txt文件中读取的数据是唯一的.

以下是样本数据;

999990  bummer
999990  bummer
999990  bummer
999990  bummer
99999   bummer
999990  bummerr
Run Code Online (Sandbox Code Playgroud)

使用Java.io.File和Java.util.Scanner读取并将其存储为Term of Term;

阅读;

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
Run Code Online (Sandbox Code Playgroud)

使用番石榴的术语类;

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);  
}
Run Code Online (Sandbox Code Playgroud)

但是,当我运行测试以检查条目存储的数组的大小时,我得到3个条目而不是1个我想要的条目.我希望任何具有与先前添加的条目相同的权重或术语的新条目被视为重复.

所有帮助表示赞赏!

马特

Jon*_*eet 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);
Run Code Online (Sandbox Code Playgroud)

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

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

  • 一组重量
  • 一套术语
  • 一组(或列表)条目.

如果您正在考虑的条目在权重集中具有权重在术语集中具有术语,则应跳过它 - 否则,您应该为三个集合中的每一个添加条目.


Men*_*ena 6

考虑到类中的hashCode(和equals)的实现Term,您应该期望3个条目,对应于所涉及的对:

999990  bummer
99999   bummer
999990  bummerr
Run Code Online (Sandbox Code Playgroud)

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

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