Java как получить значение из карты по ключу-объекту

#java #dictionary #object #hashmap

#java #словарь #объект #hashmap

Вопрос:

Я делаю реализацию graph на Java. И у меня следующая проблема: я не могу получить значение из HashMap по ключу, который является шаблонным объектом класса, точнее, мне нужно получить значение, ключ которого в двоичном представлении равен указанному ключу-объекту, но не является им (у них разные адреса в памяти). Насколько я понимаю, get(..) метод возвращает значение, адрес ключа которого равен указанному.Я не знаю, как это сделать без глупого поиска. Кстати, я пишу на C и не понимаю Java на хорошем уровне.

Вот проблемный код:

 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));
    }
  

Вот весь код:

 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;
    }
}
  

Ответ №1:

Из https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html#get-java.lang .Объект-

public V get(ключ объекта)

Возвращает значение, которому сопоставлен указанный ключ, или null, если эта карта не содержит сопоставления для ключа.

Более формально, если эта карта содержит отображение из ключа k в значение v такое, что>(key== null ? k== null: ключ.равно (k)), тогда этот метод возвращает v; в противном случае он> возвращает null . (Может быть не более одного такого сопоставления.)

Вам необходимо реализовать equals() в вашей вершине, иначе он будет смотреть только на значение equals() по умолчанию, которое должно быть исходным объектом.

Что-то вроде

 @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;
}
  

ВАЖНО:
Кроме того, вам нужно будет реализовать либо implementhashcode(), чтобы он работал в HashMap, либо compareTo() для древовидной карты.

Смотрите Такие учебные пособия, как https://www.baeldung.com/java-hashcode

Комментарии:

1. Я понял, что в том же месте я не указываю id, соответственно, эти объекты не равны, тогда ваш ответ правильный.