Java Top.

使用Spring 5和Spring Boot 2开始,通过学习春天课程:

>>查看课程

1.介绍

在本文中,我们探索生成等于()hashcode()使用Eclipse IDE的方法。我们将说明Eclipse的代码自动生成有多强大和方便,并且还强调仍然需要对代码进行勤奋测试。

2.规则

等于()在Java中用于检查2对象是否等效。一种良好的测试方法是为了确保对象是对称的,反思和传递的。也就是说,对于三个非空对象一种B., 和C

  • 对称 - AENCHALS(B)如果只有B.EQUALS(a)
  • 反身 -A.Equals(a)
  • 传播 - 如果A.Equals(b)B.Equals(c)然后A.Equals(c)

hashcode()必须遵守一个规则:

  • 2个对象等于()必须有相同的hashcode()价值

3.与基元课程

让我们考虑一个仅由基元成员变量组成的Java类:

公共类PrimitiveClass {私有布尔原始工程;私人int primiventint;//构造函数,getters和setter}

我们使用Eclipse IDE生成等于() 和哈希科特()使用'源 - >生成hashcode()等于()'。Eclipse提供如下对话框:

Eclipse等 - 哈迪德

我们可以通过选择“全选”确保所有成员变量都包含在内。

请注意,插入点下面列出的选项:影响生成的代码的样式。在这里,我们不选择任何选项,选择“确定”,并将方法添加到我们的类中:

@override public int hashcode(){final int prime = 31;结果= 1;结果= Prime *结果+(PrimitivingBoolean?1231:1237);结果= Prime *结果+原始int;返回结果;@Override公共布尔值等于(对象obj){如果(这== obj)返回true;如果(obj == null)返回false;if(getClass()!= obj.getClass())返回false;primitiveClass其他=(primitiveClass)obj;if(primitivingboolean!= oother.primitiveBoolean)返回false; if (primitiveInt != other.primitiveInt) return false; return true; }

生成hashcode()方法从素数(31)的声明开始,在原语对象上执行各种操作,并根据对象的状态返回其结果。

等于()首先检查两个对象是否相同实例(==),如果它们是返回true。

接下来,检查比较对象是非null,两个对象都是同一类的,如果它们不是,则返回false。

最后,等于()检查每个成员变量的平等,如果其中任何一个不等于,则返回false。

所以我们可以编写简单的测试:

primitiveClass AObject = New PrimitiveClass(False,2);primitiveclass bobject = new primitiveClass(false,2);primitiveClass dobject = new primitiveClass(true,2);asserttrue(aobject.equals(bobject)&& bobject.equals(aobject));asserttrue(aobject.hashcode()== bobject.hashcode());assertfalse(aobject.equals(dobject));assertfalse(aobject.hashcode()== dobject.hashcode());

4.班级带集合和仿制机

现在,让我们考虑一个带有集合和泛型的更复杂的Java类:

公共类ComplexClass {私有列表<?>泛型列表;私有设置<整数>整数;//构造函数,getters和setter}

我们再次使用Eclipse'源 - >生成hashcode()等于()'。通知hashcode()用途instanceof.要比较类对象,因为我们选择了“在对话框中的Eclipse选项中使用”使用“instanceof”来比较“类型”。我们得到:

@override public int hashcode(){final int prime = 31;结果= 1;结果= Prime *结果+((genericlist == null)?0:genericlist.hashcode());结果= Prime *结果+((integerset == null)?0:integerset.hashcode());返回结果;@Override公共布尔值等于(对象obj){如果(这== obj)返回true;如果(obj == null)返回false;if(!(OBJ instanceof complexflass))返回false;complexClass其他=(复杂的Class)OBJ;if(genericlist == null){if(other.genericlist!= null)返回false; } else if (!genericList.equals(other.genericList)) return false; if (integerSet == null) { if (other.integerSet != null) return false; } else if (!integerSet.equals(other.integerSet)) return false; return true; }

生成hashcode()方法依赖AbstractList.HashCode()抽象集.Hashcode()核心Java方法。这些迭代集合,求和hashcode()每个项目的值并返回结果。

同样,生成的等于()方法使用AbstractList.equals()AbstractSet.equals(),通过比较其字段比较相等的集合。

我们可以通过测试一些示例来验证鲁棒性:

arraylist  strarraylist = new arraylist ();strarraylist.add(“abc”);strarraylist.add(“def”);complexclass aobject = new complexclass(s​​trarraylist,new hashset <整数>(45,67));complexClass Bobject = New ComplexClass(s​​trarraylist,new hashset <整数>(45,67));arraylist  strarraylistd = new arraylist ();strarraylistd.add(“LMN”);strarraylistd.add(“PQR”);complexClass dobject = new complexclass(s​​trarraylistd,new hashset <整数>(45,67));asserttrue(aobject.equals(bobject)&& bobject.equals(aobject)); assertTrue(aObject.hashCode() == bObject.hashCode()); assertFalse(aObject.equals(dObject)); assertFalse(aObject.hashCode() == dObject.hashCode());

5.继承

让我们考虑使用继承的Java类:

公共抽象类形状{公共抽象双面区域();公共抽象双周边();公共类矩形延伸形状{私有双宽;私人双长度;@Override Public Double Digha(){返回宽度*长度;@override public double perimeter(){返回2 *(宽度+长度);} //构造函数,getters和setter}公共类广场扩展矩形{颜色;//构造函数,getters和setter}

如果我们尝试'源 - >生成hashcode()等于()“在这一点上正方形Class,Eclipse警告我们,“超级类”矩形'不会重新扣除等于()hashcode():生成的代码可能无法正常运行'。

同样,当我们尝试生成时,我们会出现关于超类“形状”的警告金宝搏官网188behashcode()等于()在这一点长方形班级。

Eclipse将使我们尽管警告汇编。如果是长方形,它延伸了一个抽象形状不能实施的课程hashcode()或者等于()因为它没有混凝土成员变量。我们可以忽略这种情况的Eclipse。

正方形但是,类继承了宽度长度来自矩形的成员变量,以及它是自己的颜色变量。创造hashcode()等于()正方形没有先做同样的事情长方形意味着只使用颜色等于()/hashcode()

@override public int hashcode(){final int prime = 31;结果= 1;结果= Prime *结果+((color == null)?0:color.hashcode());返回结果;@Override公共布尔值等于(对象obj){如果(这== obj)返回true;如果(obj == null)返回false;if(getClass()!= obj.getClass())返回false;广场其他=(正方形)OBJ;if(color == null){if(other.color!= null)返回false;}如果(!color.equals(其他.color))返回false; return true; }

一个快速测试显示我们等于()/hashcode()为了正方形如果它只是唯一的话是不够的宽度与之不同,因为宽度不包括在内等于()/hashcode()计算:

Square AObject =新广场(10,Color.Blue);Square Dobject =新广场(20,Color.Blue);assert.assertfalse(aobject.equals(dobject));assert.assertfalse(aobject.hashcode()== dobject.hashcode());

让我们通过使用Eclipse来生成它来解决此问题等于()/hashcode()为了长方形班级:

@override public int hashcode(){final int prime = 31;结果= 1;长时间;temp = double.doubletolongbits(长度);结果= Prime *结果+(int)(temp ^(temp >>> 32));temp = double.doubletolongbits(宽度);结果= Prime *结果+(int)(temp ^(temp >>> 32));返回结果;@Override公共布尔值等于(对象obj){如果(这== obj)返回true;如果(obj == null)返回false; if (getClass() != obj.getClass()) return false; Rectangle other = (Rectangle) obj; if (Double.doubleToLongBits(length) != Double.doubleToLongBits(other.length)) return false; if (Double.doubleToLongBits(width) != Double.doubleToLongBits(other.width)) return false; return true; }

我们必须重新生成等于()/hashcode()在里面正方形班级,所以长方形s等于()/hashcode()被调用。在这一代代码中,我们在Eclipse对话框中选择了所有选项,因此我们看到评论,instanceof.比较和如果块:

@override public int hashcode(){final int prime = 31;int结果= super.hashcode();结果= Prime *结果+((color == null)?0:color.hashcode());返回结果;@Override公共布尔值等于(对象obj){if(== obj){return true;}如果(!超级等等(OBJ)){返回false;}如果(!(OBJ instanceof square)){返回false;} Square其他=(方形)OBJ;if(color == null){if(其他.color!= null){返回false;}}否则如果(!color.equals(其他.color)){返回false; } return true; }

从上面重新运行我们的测试,我们现在通过了,因为正方形shashcode()/等于()正确计算。

六,结论

Eclipse IDE非常强大,允许自动生成样板代码 - Getter / Setter,各种类型的构造函数,等于(), 和hashcode()

通过了解Eclipse在做什么,我们可以减少在这些编码任务上花费的时间。但是,我们仍必须谨慎谨慎并验证我们的代码是否有测试,以确保我们处理所有预期案例。

可以找到代码片段,可以找到在github上

Java底部

使用Spring 5和Spring Boot 2开始,通过学习春天课程:

>>查看课程
4.注释
最老的
最新
内联反馈
查看所有评论
评论在本文上关闭!