Niepowtarzalność w kolekcji HashSet

0

Potrzebowałem takie coś

   HashSet<Punkt> punkty;

gdzie klasa Punkt jest dość podobna do klasy standardowej Point.
Pierwsze podejście

class Punkt implements Comparable
...
    public boolean equals(Object ob)
    {
        Punkt p=(Punkt)ob;
        if(x==p.x && y==p.y)
            return true;
        else
            return false;
    }

nieudane, w kolekcji było tyle punktów ile dodałem (niektóre się powtarzały).
Drugie podejście

class Punkt extends Point implements Comparable
...
    public boolean equals(Object ob)
    {
        Punkt p=(Punkt)ob;
        if(x==p.x && y==p.y)
            return true;
        else
            return false;
    }

działą
Trzecie podejście

class Punkt extends Point implements Comparable
...
    /*public boolean equals(Object ob)
    {
        Punkt p=(Punkt)ob;
        if(x==p.x && y==p.y)
            return true;
        else
            return false;
    }* metoda equals nie została nadpisana/

kolekcja zawiera zawsze dokładnie jeden punkt.
Czym się kieruje metoda add() w klasie HashSet<E> podczas dodawania elementów? (Wg dokumentacji metodą equals() w klasie E).

0

Najpierw wylicza hash za pomoca hashCode() aby odnalezc koszyk do ktorego wrzuci dodawany element. Jesli ten koszyk jest pusty, wiadomo ze nie bylo nic takiego samego wczesniej. Jesli ma elementy, to sprawdza za pomoca equals() czy dany element jest rowny dla ktoregokolwiek w danym koszyku.
We fragmentach kodu ktory podales nie widze metody hasCode(), wiec albo nie trzymasz sie kontraktu (zawsze implementuj hashCode() gdy implementujesz equals() i odwrotnie) albo pominales to w kodzie ktory tu wkleiles, i mamy wieksza zagadke.
Pierwsza proba: brak hashCode(), wiec kazdy punkt ma unikalny hashCode(), wiec wszystkie dodane.
Druga: dziedziczysz po Point z JDK ktora implementuje hashCode(), dlatego dziala.
Trzeciego nie potrafie wytlumaczyc, musialbym uruchomic kod i zobaczyc co sie dzieje ;d
Pozdro.

0

Mea culpa, nie dotrzymałem kontraktu i nie zaimplementowałem hashCode(). Teraz działa klasa Punkt nie dziedzicząca po klasie Point. Co więcej działa lepiej niż dziedzicząca. Mianowicie działa metoda remove(). Czy można wnioskować, że klasa Point nie dotrzymuje kontraktu?

0

Jesli jest jak mowisz, to moze to byc bug. Faktem jest ze i hashCode() i equals() sa zaimplementowane poprzez dziedziczenie po Point2D, ale zauwazylem ze equals() uzywa == do porownywania doubli / floatow (zalezy czy uzywasz Point2D.Float czy Double) (a zawsze sie mowi zeby tak nie porownywac bo moga byc jakies arytmetyczne zonki), a hashCode() zamienia pola double na bity, i za pomoca bitow oblicza hash. Jak by nie patrzec jest to inna implementacja, moze to jest powodem? Jesli tak to moze warto zglosic.

1 użytkowników online, w tym zalogowanych: 0, gości: 1