简体   繁体   English

HashSet 与 TreeSet 不同的大小()

[英]HashSet vs TreeSet different size()

I'm reading a file and adding the words to a HashSet and a TreeSet .我正在读取文件并将单词添加到HashSetTreeSet HashSet.size() gives me 350 items but TreeSet.size() 349 items. HashSet.size()给了我350项,但TreeSet.size() 349项。 Does anyone have an explanation of this difference?有没有人解释这种差异?

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


}

Change your equals from equals(Word) to equals(Object) .将您的 equals 从equals(Word)更改为equals(Object) Please also add @Override attribute.还请添加@Override属性。

Moreover, your hashCode method does not guarantee that for two words that are equal (ignoring case), they will have the same hash code.此外,您的hashCode方法不能保证对于相等的两个单词(忽略大小写),它们将具有相同的哈希码。 You can use toUpperCase() on word before computing the hash code.您可以在计算哈希码之前对word使用toUpperCase()

Your equals and compareTo method behaves differently for same input.对于相同的输入,您的equalscompareTo方法的行为不同。 Eg例如

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

will give会给

false
true
0

HashSet uses equals method to compare keys, while TreeSet will use compareTo method to check equivalence of keys. HashSet 使用equals方法比较键,而 TreeSet 将使用compareTo方法检查键的等效性。 Since your implementation is not correct, for different scenarios, hashset will treat keys as different while treeset might be considering them as same.由于您的实现不正确,对于不同的场景,hashset 会将键视为不同,而 treeset 可能会将它们视为相同。

To know which values are getting treated as same by TreeSet you can print the result of addition to the Sets.要知道 TreeSet 将哪些值视为相同,您可以打印添加到 Sets 的结果。 Both will return true, if key does not exist otherwise false is returned.两者都将返回真,如果键不存在,否则返回假。

while(read.hasNext()) {
    Word word = new Word(read.next());
    System.out.println(hashSet.add(word));
    System.out.println(treeSet.add(word));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM