Java如何通过key-object从Map中获取值

huangapple go评论58阅读模式
英文:

Java how to get value from Map by key-object

问题

我正在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;
    }
}
英文:

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&lt;V&gt;(v1)).put(new Vertex&lt;V&gt;(v2), new Edge&lt;E&gt;(edg));
nodes.get(new Vertex&lt;V&gt;(v2)).put(new Vertex&lt;V&gt;(v1), new Edge&lt;E&gt;(edg));
}

Here's the whole code:

import java.util.*;
class Vertex&lt;Node&gt; {
Node node;
int id;
Vertex(Node val) {
this.node = val;
}
Vertex(Node val, int id) {
this.node = val;
this.id = id;
}
}
class Edge&lt;T&gt; {
T value;
Edge(T val) {
this.value = val;
}
}
public class Graph&lt;V, E&gt; {
private Map&lt;Vertex&lt;V&gt;, HashMap&lt;Vertex&lt;V&gt;, Edge&lt;E&gt;&gt;&gt; nodes;
Graph() {
nodes = new HashMap&lt;Vertex&lt;V&gt;, HashMap&lt;Vertex&lt;V&gt;, Edge&lt;E&gt;&gt;&gt;();		
}
public void addVertex(V ver, int id) {
nodes.put(new Vertex&lt;V&gt;(ver, id), new HashMap&lt;Vertex&lt;V&gt;, Edge&lt;E&gt;&gt;());
}
public void addEdge(V v1, V v2, E edg) {
nodes.get(new Vertex&lt;V&gt;(v1)).put(new Vertex&lt;V&gt;(v2), new Edge&lt;E&gt;(edg));
nodes.get(new Vertex&lt;V&gt;(v2)).put(new Vertex&lt;V&gt;(v1), new Edge&lt;E&gt;(edg));
}
public V getNode(int id) {
for(Vertex&lt;V&gt; el: nodes.keySet())
if(el.id == id)
return el.node;
return null;
}
}

答案1

得分: 1

// 从 https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html#get-java.lang.Object- 处翻译的内容:

/**
 * 获取与指定键关联的值,如果该映射不包含键的映射,则返回 null。
 * 更正式地说,如果该映射包含从键 k 到值 v 的映射,使得 (key==null ? k==null : key.equals(k)),
 * 则该方法返回 v;否则返回 null。(最多可能存在一个这样的映射。)
 */
public V get(Object key) {
    // 方法实现
}

// 在您的顶点类中需要实现 equals() 方法,否则它只会使用默认的 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;
}

// 重要提示:
// 此外,您需要实现 hashcode() 方法使其在 HashMap 中工作,或者实现 compareTo() 方法使其在 TreeMap 中工作。
// 请参阅诸如 https://www.baeldung.com/java-hashcode 的教程。
英文:

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

huangapple
  • 本文由 发表于 2020年10月13日 00:01:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/64321324.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定