Artem072
Artem072

Reputation: 133

Java how to get value from Map by key-object

I am doing a graph implementation in java. And I have the following problem: I cant get value from HashMap by key which is a templated class object, more precisely, I need to get a value whose key in binary representation is equal to the specified key-object, but is not it (they have different addresses in memory). As I understand it, the get(..) method returns a value whose key address is equal to the specified one.I don’t know how to do it without a stupid search. By the way, I write in C ++ and don't understand Java at a good level.

Here's the problematic code:

public void addEdge(V v1, V v2, E edg) {        
        nodes.get(new Vertex<V>(v1)).put(new Vertex<V>(v2), new Edge<E>(edg));
        nodes.get(new Vertex<V>(v2)).put(new Vertex<V>(v1), new Edge<E>(edg));
    }

Here's the whole code:

import java.util.*;

class Vertex<Node> {
    Node node;
    int id;

    Vertex(Node val) {
        this.node = val;
    }

    Vertex(Node val, int id) {
        this.node = val;
        this.id = id;
    }
}

class Edge<T> {
    T value;

    Edge(T val) {
        this.value = val;
    }
}

public class Graph<V, E> {
    private Map<Vertex<V>, HashMap<Vertex<V>, Edge<E>>> nodes;

    Graph() {
        nodes = new HashMap<Vertex<V>, HashMap<Vertex<V>, Edge<E>>>();      
    }

    public void addVertex(V ver, int id) {
        nodes.put(new Vertex<V>(ver, id), new HashMap<Vertex<V>, Edge<E>>());
    }

    public void addEdge(V v1, V v2, E edg) {
        
        nodes.get(new Vertex<V>(v1)).put(new Vertex<V>(v2), new Edge<E>(edg));
        nodes.get(new Vertex<V>(v2)).put(new Vertex<V>(v1), new Edge<E>(edg));
    }

    public V getNode(int id) {
        for(Vertex<V> el: nodes.keySet())
            if(el.id == id)
                return el.node;
        return null;
    }
}

Upvotes: 2

Views: 1153

Answers (1)

pdewilde
pdewilde

Reputation: 306

From https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html#get-java.lang.Object-

public V get(Object key)

Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.

More formally, if this map contains a mapping from a key k to a value v such that >(key==null ? k==null : key.equals(k)), then this method returns v; otherwise it >returns null. (There can be at most one such mapping.)

You need to implement equals() in your vertex, otherwise it will only look at the default equals() which has to be the original object.

Something like

@Override
public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Vertex that = (Vertex) o;
        if (node != null ? !node.equals(that.node) : that.node != null) return false;
        return this.id == that.id;
}

IMPORTANT: Additionally, you will need to implement either implement hashcode() for it to work in a HashMap, or compareTo() for a tree map.

See tutorials such as https://www.baeldung.com/java-hashcode

Upvotes: 1

Related Questions