重写equals() 和hashCode()

发生了甚么

做项目时在构建函数调用图时明明把所有的结点和边信息都写入图中了,但在Echarts生成的图中结点间并没有边。

构建的图使用到了4个类:

  1. classInfo 结点信息类、
  2. clsasNode 结点类,包含classInfo类
  3. classEdge 边类,包含了两个classNode类
  4. classGraph 图类,包含了所有结点类和边类

原来是这样

原因是将图片转为echarts所需要的json格式时使用了HashMap遍历添加了图中所有结点,之后在把结点和边信息存为json时使用了HashMap中的containsKey方法,containsKey方法中使用了equals和hashCode方法,没有重写这两个方法导致了containsKey在判断时认为两个值相等的不同对象并不相等。

用上面的图举例子就是:

  1. 声明一个 HashMap<classEdge, Integer> map
  2. 声明一个classEdge变量edge1 = new classEdge(classNode1, classNode2) ,并添加进map中 map.put(edge1, 1)
  3. 使用map.containsKey(new classEdge(classNode1, classNode2)) 时结果为false,因为虽然边的两个node是相同的,但是因为没有重写equals和hashCode方法,这两个边被认为是不同的

我啪的一下解决了,很快啊

解决方法就是每个类中都重写了hashCode和equals方法。在Idea里可以自动生成这两个方法,超方便。

那为什么重写equals方法也必须重写hashCode呢,首先有下面的规定:

  1. 如果两个对象通过equals方法比较是相等的,那么要求这两个对象的hashCode方法返回的值也应该是相等的。
  2. 如果两个对象通过equals方法比较是不同的,那么也不要求这两个对象的hashCode方法返回的值是不相同的。但是我们应该知道对于不同对象产生不同的哈希值对于哈希表(HashMap等等)能够提高性能。

所以如果不重写hashcode方法,那么两个不同的对象equals时,hash值却不同,如果把对象用在map中作为键使用时就会出现上面的错误。