HashMapa - zwraca null dla klucza

0

Cześć,

Potrzebuję pomocy z HashMapą. Pewnie jako początkujący czegoś tu nie widzę..

Jest klasa abstrakcyjna AbstractWorldMap:

public abstract class AbstractWorldMap{

private Map<Vector2d, ArrayList<IMapElement>> objectsOnMap;

    public AbstractWorldMap(int width, int height){
(...)
        this.objectsOnMap = new HashMap<>();
    }

    @Override
    public boolean place(IMapElement mapElement) {
        ArrayList<IMapElement> newElement = this.objectsOnMap.getOrDefault(mapElement.getPosition(), new ArrayList<>());
        if (newElement.size() == 0){
            newElement.add(mapElement);
        } else{
            if (!isOccupied(mapElement.getPosition())){ //zwraca true jeśli na danej pozycji jest obiekt, false - jeśli nic nie ma
                newElement.add(mapElement);
            }
        }
        objectsOnMap.put(mapElement.getPosition(), newElement);
        return true;
    }

    @Override
    public boolean isOccupied(Vector2d position){
        Set<Vector2d> positionKeys  = objectsOnMap.keySet();
        for (Vector2d p : positionKeys){
            if (p.equals(position)){
                for (IMapElement mapElement : objectsOnMap.get(p)) {
                    if (mapElement instanceof Animal) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    @Override
    public IMapElement objectAt(Vector2d position) {
        return printFirst(objectsOnMap.get(position)); // <----------- zwraca pustą ArrayList
    }

}

i teraz - metodą place dodaję obiekt do mapy i w mapie mam np: <(2, 2); lista obiektów> - czyli na współrzędnych (2,2) dodałem obiekt (do ArrayList).

Klucz (pozycje, współrzędne to prosta klasa:

public class Vector2d {
    private final int x;
    private final int y;

    public Vector2d(int x, int y){
        this.x = x;
        this.y = y;
    }

public boolean equals(Vector2d other){
        return this.x == other.x && this.y == other.y;
    }

   @Override
    public int hashCode() {
        return Objects.hash(this.x, this.y);
    }

Metoda isOccupied dla zadanego Vector2d zwraca mi TRUE. W debuggerze widzę też, że jest wartość - lista obiektów dla tego klucza. Natomiast chwilę potem kiedy wywołuję metodę objectAt - objectsOnMap.get(position) zwraca null... Dlaczego?

5

na poczatek - zamiast equals(Vector2d other) powinno byc equals(Object other) w klasie Vector2d, uzywaj jakiegos IDE to ci wylapie takie bledy

0

@katelx: jak wtedy miałoby wyglądać porównanie dwóch punktów? this.x == other.x && this.y == other.y ? W klasie Object nie ma x ani y...

PS: używam IDE :)

2

@4m4ru:

PS: używam IDE

w takim razie jest tam gdzies opcja override "equals" (z klasy Object) albo "generate equals".
Wygeneruj. Zobacz. Popłacz trochę nad Javą i idź dalej. Da się przyzwyczaić.

Zresztą, ten Vector2d to książkowy przykład na użycie rekordów. Użyj (https://www.baeldung.com/java-record-keyword).

0

Myślałem, że problem jest w metodzie hashCode a tu jednak faktycznie problem był w equals, a wydawała się być poprawna..
Dodałem do klasy Vector2d metody:

    @Override
    public boolean equals(Object other){
        if (!(other instanceof Vector2d)){
            return false;
        } else {
            return equals((Vector2d) other);
        }
    }

    public boolean equals(Vector2d other){
        return this.x == other.x && this.y == other.y;
    }

i zadziałało. Dzięki za pomoc :) jadę dalej.

1

W tej implementacji jest jeszcze jeden błąd:
https://ideone.com/bHit0T

0
4m4ru napisał(a):

@katelx: jak wtedy miałoby wyglądać porównanie dwóch punktów? this.x == other.x && this.y == other.y ? W klasie Object nie ma x ani y...

PS: używam IDE :)

IDE moze tez automatycznie wygenerowac equals tak zeby zminimalizowac bledy, np:

@Override
public boolean equals(Object obj){
    if(this == obj) return true;
    if(obj == null || getClass() != obj.getClass()) return false;
    final Vector2d other = (Vector2d)obj;
    return x == other.x && y == other.y;
}

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