2

主要问题
我有一个充满顶点对象的哈希图。基于一个整数(即 1),我想找到那个顶点对象。请看下面的代码:

public class Playground {

    public static void main(String[] args) {
        Map<Vertex, String> map1 = new HashMap<Vertex, String>();
        Map<Integer, String> map2 = new HashMap<Integer, String>(); 

        Vertex v1 = new Vertex(5);
        map1.put(v1, "1");
        Vertex v2 = new Vertex(5);
        String s = map1.get(v2);
        System.out.println(s);

        Integer int1 = new Integer(1);
        map2.put(int1, "2");
        Integer int2 = new Integer(1);
        String t = map2.get(int2);
        System.out.println(t);
    }
}

class Vertex{

    public int id;

    public Vertex(int id){
        this.id = id;
    }

    @Override
    public boolean equals(Object obj) {
        Vertex v = (Vertex) obj;

        return (this.id == v.id);
    }
}

输出:

2

正如您在上面看到的,它适用于 Integer 对象,但不适用于用户定义的 Vertex 对象。我也覆盖了 equals 方法。

附加信息 我有一个文本文件。第一列表示边的尾部。第二个边缘的头部。这是摘录:
1 1
1 2
1 8
1 4
2 47646
2 47647
...

我预加载顶点 1 - n 因为......嗯......我无法每次都检查我的地图的键集以查看顶点是否已经存在。
无论如何,那么,基于这个文本文件,我需要找到 id 为“x”的顶点并添加一条边。

您可能会问为什么我不使用 Integer 对象作为键。许多在线示例都使用了通用 V 对象,这很有意义 --- 每个节点 (irl) 都会有额外的信息,无论是停靠点的名称还是其他信息。

4

3 回答 3

2

您需要重写该hashCode方法以使 JVM 在 HashMap 中正确存储和检索您的对象。

当对HashMap等散列集合调用put方法时,会调用关键对象hashcode方法来决定存储对象的桶。然后调用它的 equals 方法来查看那里是否已经存在某些东西。

类似地,当您在 HashMap 上进行获取时,将调用 key hashCode 方法来查找存储桶并检索对象。

由于您没有覆盖 Vertex 类中的 hashcode 方法,因此使用了默认的 hashcode 实现。因此,具有相同 id 值的两个 Vertex 对象可能具有不同的哈希码。

阅读这篇相关文章以了解如何覆盖 equals 和 hashcode 方法:

在 Java 中覆盖 equals 和 hashCode 时应该考虑哪些问题?

您可以在 google 上找到同一主题的不同文章。一个好的谷歌结果:

http://javarevisited.blogspot.in/2011/02/how-to-write-equals-method-in-java.html

于 2013-07-31T17:44:16.593 回答
1

您需要在课堂上添加方法并hashCode()修复您的equals()Vertex

尝试这个:

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

        Vertex vertex = (Vertex) o;

        if (id != vertex.id) return false;

        return true;
    }

    @Override
    public int hashCode() {
        return id;
    }
于 2013-07-31T17:47:07.283 回答
0

映射用于hashCode()确定与请求匹配的对象。equals()Comparable类使用。即使提供的属性相等,也不能保证两个对象相同。

它与Integer对象一起工作的原因是因为Integer该类只是原始int类型的包装器,并且该类的所有其他属性/方法Integer都与另一个Integer对象相同。

于 2013-07-31T17:58:12.667 回答