HashSet против TreeSet другого размера () - PullRequest
1 голос
/ 12 марта 2020

Я читаю файл и добавляю слова в 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;
        }


}

Ответы [ 2 ]

2 голосов
/ 12 марта 2020

Измените свои равные с equals(Word) на equals(Object). Также добавьте атрибут @Override.

Кроме того, ваш метод hashCode не гарантирует, что для двух одинаковых слов (без учета регистра) они будут иметь одинаковый код ha sh. Вы можете использовать toUpperCase() на word перед вычислением кода ha sh.

1 голос
/ 12 марта 2020

Ваш метод 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 для проверки эквивалентности ключей. Поскольку ваша реализация неверна, для другого сценария ios hashset будет обрабатывать ключи как разные, в то время как treeset может рассматривать их как одинаковые.

Чтобы узнать, какие значения обрабатываются TreeSet как одинаковые, вы можете напечатать результат добавления в наборы. Оба возвращают значение true, если ключ не существует, в противном случае возвращается значение false.

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