我正在读取文件,并将单词添加到HashSet
和TreeSet
中。 HashSet.size()
给了我350个物品,但TreeSet.size()
给了我349个物品。有人对此有解释吗?
public static void main(String[] args) throws FileNotFoundException {
File file = new File("src/words.txt");
Scanner read = new Scanner(file);
Set<Word> hashSet = new HashSet<Word>();
Set<Word> treeSet = new TreeSet<Word>();
while(read.hasNext()) {
Word word = new Word(read.next());
hashSet.add(word);
treeSet.add(word);
}
System.out.println(hashSet.size());
System.out.println(treeSet.size());
Iterator<Word> itr = treeSet.iterator();
while (itr.hasNext()) {
System.out.println(itr.next().toString());
}
}
public class Word implements Comparable<Word> {
private String word;
public Word(String str) {
this.word = str; }
public String toString() {
return word.toLowerCase(); }
/* Override Object methods */
public int hashCode() {
int hashCode = 0;
int temp;
for(int i = 0; i<word.length();i++){
temp = (int) word.charAt(i);
hashCode += temp^hashCode;
}
return hashCode;
}
public boolean equals(Word other) {
if(other instanceof Word){
if(compareTo(((Word) other))==0)
return true;
else
return false;}
else
return false;
}
public int compareTo(Word w) {
if(this.word.compareToIgnoreCase(w.toString())>0)
return 1;
if(this.word.compareToIgnoreCase(w.toString())<0)
return -1;
else
return 0;
}
}
答案 0 :(得分:2)
将您的等值从equals(Word)
更改为equals(Object)
。还请添加@Override
属性。
此外,您的hashCode
方法不能保证对于相等的两个单词(忽略大小写),它们将具有相同的哈希码。在计算哈希码之前,可以在toUpperCase()
上使用word
。
答案 1 :(得分:1)
对于相同的输入,您的equals
和compareTo
方法的行为有所不同。
例如
Word w1 = new Word("Word");
Word w2 = new Word("word");
System.out.println(w1 == w2);
System.out.println(w1.equals(w2));
System.out.println(w1.compareTo(w2));
会给出
false
true
0
HashSet使用equals
方法比较密钥,而TreeSet将使用compareTo
方法检查密钥的等效性。由于您的实现不正确,因此对于不同的情况,哈希集会将键视为不同,而树集可能会将其视为相同。
要知道TreeSet将哪些值视为相同,可以打印添加到Set中的结果。如果键不存在,两者都将返回true,否则返回false。
while(read.hasNext()) {
Word word = new Word(read.next());
System.out.println(hashSet.add(word));
System.out.println(treeSet.add(word));
}