HashSet与TreeSet不同的size()

时间:2020-03-12 10:55:59

标签: java hashset treeset

我正在读取文件,并将单词添加到HashSetTreeSet中。 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;
        }


}

2 个答案:

答案 0 :(得分:2)

将您的等值从equals(Word)更改为equals(Object)。还请添加@Override属性。

此外,您的hashCode方法不能保证对于相等的两个单词(忽略大小写),它们将具有相同的哈希码。在计算哈希码之前,可以在toUpperCase()上使用word

答案 1 :(得分:1)

对于相同的输入,您的equalscompareTo方法的行为有所不同。 例如

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));
}