HashSet添加重复的对象

veo*_*ote 1 java set hashcode

我有一个HashSet,它在Graph中存储了一些边.每个Edge都有两个节点.

在图表未定向的情况下,添加副本应该失败:

Edge a = new Edge(new Node("aa"), new Node("bb"));
Edge duplicate = new Edge(new Node("aa"), new Node("bb"));
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

编辑:好的,现在我添加了一个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;
    }
Run Code Online (Sandbox Code Playgroud)

fge*_*fge 5

正如评论中所提到的......

你必须实现.equals().hashCode()BOTH类EdgeNode.

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

由于您没有覆盖它们中的任何一个,因此这些方法的实现是以下方法之一Object:

  • .hashCode() 是对象的引用地址的简单哈希;
  • .equals()当且仅当两个对象都是相同的引用时(即o1 == o2),才为真.

这显然不是你想要的!