Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> разное переопределение equals, переопределение для HashMap и TreeMap 
V
    Опции темы
Pawl
Дата 13.3.2011, 12:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: 7
Всего: 28



Доброго времени суток Господа!
Решил поднять этот вопрос, т. к. не нашел ответа в предложенных мне автоматических ссылках на похожие темы.
Вопрос вот какой:
есть код:
Код

import java.util.HashMap;
import java.util.Set;
import java.util.Iterator;
import java.util.Map;

class Student {
    private String forName, lastName;
    
    public Student(String f, String l) {
        forName = f;
        lastName = l;
    }
    
    public int hashCode() {
        return (forName.hashCode() + lastName.hashCode()) * 17;
    }
    
    public boolean equals(Object o) {
        if(!(o instanceof Student)) {
         return false;
        }
                        
        Student s = (Student)o;
        if (forName.equals(s.forName) && lastName.equals(s.lastName)) {
         return true;
        }
        
        return false;
    }
       
    public String toString() {
        return forName + " " + lastName;
    }    
}

public class StudentList {
    private HashMap<Student, Integer> attestList = new HashMap<Student, Integer>();
    
    public void attestStudent(String forName, String lastName, Integer note) {
        Student s = new Student(forName, lastName);
        attestList.put(s, note);
    }
    
    public void showStudents() {
        Iterator<Map.Entry<Student, Integer>> list = attestList.entrySet().iterator();
        while (list.hasNext()) {
            Map.Entry me = list.next();
            System.out.printf("%-15s%d%n", me.getKey(), me.getValue());
        }
    }
    
    public static void main(String ...args) {
        StudentList sl = new StudentList();
        sl.attestStudent("Piter", "Pen", 8);
        sl.attestStudent("Jon", "Dow", 7);
        sl.attestStudent("Piter", "Pen", 9);
        sl.showStudents();
    }
}

как видно, тут я переопределяю в классе Student методы hashCode и equals для того, чтобы в HashMap не попадали студенты с одинаковыми именами. И тут они действительно туда не попадают.
Вывод программы:

Piter Pen      9
Jon Dow        7

но если я переопределяю equals так:
Код

//...
    public boolean equals(Student s) {
        if (forName.equals(s.forName) && lastName.equals(s.lastName)) {
         return true;
        }
        
        return false;
    }
//...

вывод уже такой:

Piter Pen      9
Piter Pen      8
Jon Dow        7

В то же время, если вместо HashMap использовать TreeMap таким образом:
Код

import java.util.TreeMap;
import java.util.Set;
import java.util.Iterator;
import java.util.Map;

class Student implements Comparable<Student> {
    private String forName, lastName;
    
    public Student(String f, String l) {
        forName = f;
        lastName = l;
    }
    
    public int hashCode() {
        return (forName.hashCode() + lastName.hashCode()) * 17;
    }
    
    public boolean equals(Student s) {
        if (forName.equals(s.forName) && lastName.equals(s.lastName)) {
            return true;
        }
        
        return false;
    }
    
    public int compareTo(Student s) {
        return lastName.compareTo(s.lastName);
    }
       
    public String toString() {
        return forName + " " + lastName;
    }    
}

public class StudentList {
    private TreeMap<Student, Integer> attestList = new TreeMap<Student, Integer>();
    
    public void attestStudent(String forName, String lastName, Integer note) {
        Student s = new Student(forName, lastName);
        attestList.put(s, note);
    }
    
    public void showStudents() {
        Iterator<Map.Entry<Student, Integer>> list = attestList.entrySet().iterator();
        while (list.hasNext()) {
            Map.Entry me = list.next();
            System.out.printf("%-15s%d%n", me.getKey(), me.getValue());
        }
    }
    
    public static void main(String ...args) {
        StudentList sl = new StudentList();
        sl.attestStudent("Piter", "Pen", 8);
        sl.attestStudent("Jon", "Dow", 7);
        sl.attestStudent("Piter", "Pen", 9);
        sl.showStudents();
    }
}

Вывод получается каким надо (т. е. Piter Pen заменяется).
Вообще, любой стандартный класс, реализующий Map, в котором присутствует слово Hash, корректно работает только с equals, переопределенным "по старинке" (я проверял smile ). Вот и прошу, может, кто разъяснит мне почему в одном случае можно в equals использовать конкретный класс вместо Object, а в другом - нет?
Заранее благодарю!


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
Pawl
Дата 13.3.2011, 15:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: 7
Всего: 28



Извините, затупил!
equals в любом случае принимает только Object, а для TreeMap eqauls вовсе переопределять не надо, достаточно одного hashCode.
Тему закрываю.


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
Pawl
Дата 13.3.2011, 16:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: 7
Всего: 28



З. ы. Кстати, hashCode для TreeMap тоже переопределять не нужно...


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0824 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.