JorgeeFG
JorgeeFG

Reputation: 5981

Java HashSet doesn't add two objets with same hashCode and equals (OK) but contains() says second object is not in set

I have a test for testing that adding the same Edge (Arista) but with the same vertices (but flipped order) is the same (this is not a directed graph).

And this is strange because the two first assertions passes OK (adding Edge1 and Edge2 will result in edges.sizes = 1 because they are the same, theoretically).

But then when testing that edges.contains(Edge2) returns false.

Why could it have worked when testing addition (to not add it duplicated) but does not work when testing contains()?

This is the code:

    @Test
public final void testAristaWithSameVerticesIsNotAddedTwice() throws Exception {
    Grafo grafo = new Grafo();
    Vertice vertice1 = new Vertice("Vertice 1");
    Vertice vertice2 = new Vertice("Vertice 2");
    grafo.agregarVertice(vertice1);
    grafo.agregarVertice(vertice2);
    Arista arista = new Arista(vertice1, vertice2, 10);
    Arista arista2 = new Arista(vertice2, vertice1, 10);
    grafo.agregarArista(arista);
    grafo.agregarArista(arista);

    assertEquals(1, grafo.getAristasQuantity());
    assertTrue(grafo.hasArista(arista));
    assertTrue(grafo.hasArista(arista2)); // fails here
}

Grafo class:

private HashSet<Arista> aristas;

public boolean hasArista(Arista arista) {
    return this.aristas.contains(arista);
}

Arista class

package entities;

public class Arista {

    protected Vertice vertice1;
    protected Vertice vertice2;
    protected int peso;

    public Arista(Vertice vertice1, Vertice vertice2, int peso) {
        this.vertice1 = vertice1;
        this.vertice2 = vertice2;
        this.peso = peso;
    }

    public Vertice getVertice1() {
        return vertice1;
    }

    public Vertice getVertice2() {
        return vertice2;
    }

    public int getPeso() {
        return peso;
    }

    public void setPeso(int peso ) {
        this.peso = peso;
    }

    public int hashCode() {
        return vertice1.hashCode() + vertice2.hashCode();
    }

    public boolean equals(Arista arista) {
        if (arista == this) {
            return true;
        }
        if ((arista.getVertice1() == this.vertice1 && arista.getVertice2() == this.vertice2)
            || (arista.getVertice2() == this.vertice1 && arista.getVertice1() == this.vertice2)) {
            return true;
        }
        return false;
    }
}

Upvotes: 0

Views: 42

Answers (1)

JorgeeFG
JorgeeFG

Reputation: 5981

I found out that the equals() wasn't overriding the parent definition because it was not well defined. So it wasn't being called.

Correct way is:

@Override
public boolean equals(Object object) {
    if (object instanceof Arista) {
        Arista arista = (Arista) object;
        if (arista == this) {
            return true;
        }
        if ((arista.getVertice1() == this.vertice1 && arista.getVertice2() == this.vertice2)
            || (arista.getVertice2() == this.vertice1 && arista.getVertice1() == this.vertice2)) {
            return true;
        }
    }
    return false;
}

Upvotes: 1

Related Questions