java - HashSet 添加重复对象

标签 java set hashcode

<分区>

我有一个 HashSet,它在图形中存储一些边。 每条边有两个节点。

如果图是无向的,添加副本应该会失败:

Edge a = new Edge(new Node("aa"), new Node("bb"));
Edge duplicate = new Edge(new Node("aa"), new Node("bb"));

但在下面的例子中它起作用了:

System.out.println(a.equals(duplicate));

Set<Edge> sete = new HashSet<Edge>();
System.out.println(sete.contains(a));
System.out.println(sete.add(a));
System.out.println(sete.contains(duplicate));
System.out.println(sete.add(duplicate));

Output:
true

false
true
false
true

编辑: 好的,现在我已经添加了一个 hashCode 方法,它适用于有向边。 有人可以帮我计算无向边的哈希值吗?

public class Edge {
    private Node first, second;

    @Override
    public /boolean equals(Object ob) {
        if (ob instanceof Edge) {
            Edge edge = (Edge) ob;
            if (first.equals(edge.first)
                    && second.equals(edge.second)
                    || first.equals(edge.second)
                    && second.equals(edge.first))
                return true;
        }
        return false;
   }


    @Override
    public int hashCode() {
        int hash = 17;
        int hashMultiplikator = 79;
        hash = hashMultiplikator * hash
                + first.hashCode();
        hash = hashMultiplikator * hash
                + second.hashCode();
        return hash;
    }

最佳答案

如评论中所述...

您必须为 EdgeNode 这两个类实现 .equals().hashCode()

HashSet 使用.hashCode() 来确定放置新条目的哈希桶;如果此存储桶中已有条目,它会在存储桶的每个条目上使用 .equals() 来查看该条目是否已存在。

因为您没有重写它们中的任何一个,所以这些方法的实现是 Object 之一:

  • .hashCode() 是对象引用地址的简单散列;
  • .equals() 为真当且仅当两个对象是相同的引用(即 o1 == o2)。

这显然不是你想要的!

关于java - HashSet 添加重复对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16980102/

相关文章:

.net - 有没有办法使用 ReSharper 自动生成 GetHashCode 和 Equals?

java - 将 Eclipse(Java) 连接到 Oracle 数据库

java - Android JavaMail 检测服务器是否离线

lua - 如何使用一些命令或 LUA 脚本读取存储在 Redis 上的多个集合

java - 为什么在将重复项目添加到 Set 时不会出现错误?

c++ - 将字符串集中的元素添加到字符串集的 vector 中

dart - 在Dart中,hashCode()方法调用能否在相等(==)的对象上返回不同的值?

java - HashMap 的 containsKey 方法返回 false,但它的键是 integer[] 类型?

java - 塔基过滤器 - https 重定向

java - Fragment 上的 onPostExecute(AsyncTask) 中的 ArrayList 为空