如前文所述,在覆盖了equals方法的类中,也必须覆盖hashCode方法。否则违反了Object.hashCode的通用约定会导致该类无法和基于散列的集合(HashMap,HashSet和HashTable)一起正常使用。
如下约定内容摘自Object规范:
1. 在应用程序中,只要对象的euqals方法的比较操作所用的信息没有修改,那么对于同一个对象的调用多次hashCode,必须始终如一返回同一个哈希值。
2. 如果两个对象通过equals比较相等,那么它们的哈希值相同。
3. 如果两个对象通过euqals比较不等,他们的哈希值可能相同,取决于hashCode的实现,由此散列表的性能也会有区别。
以前面的PhoneNumber类为例,编写了如下的测试用例:
@Test
public void testHashCode(){
PhoneNumber pn1 = new PhoneNumber(86, "12345");
PhoneNumber pn2 = new PhoneNumber(86, "12345");
Map<PhoneNumber,String> map = new HashMap<PhoneNumber,String>();
map.put(pn1, "12345");
assertNotNull(map.get(pn2));
}
发现测试失败了,但是两个对象通过equals比较是相等的。由于并没有覆盖hashCode方法导致两个相等的对象不能获得相同的散列码。根据约定重写hashCode:
@Override
public int hashCode(){
int result = 17;
result = 31 * result + countryCode;
if(nationalNumber != null)
result = 31 * result + nationalNumber.hashCode();
return result;
}
好的散列函数通常倾向于"为不相等的对象产生不相等的散列码", 否则会引起冲突,使散列表想链表退化。计算是可以把冗余的域排除在外。注意不要试图从散列码计算中排除关键域来提高性能。
分享到:
相关推荐
重写equals方法需要遵守通用约定,hashCode方法的实现需要保证equals相同的两个对象的hashCode结果一致。ArrayList、Vector和LinkedList是Java中三种常见的容器集合,每种集合都有其特点和应用场景。
此外,Object 类的设计是为了扩展,它提供了一些非 final 方法,如 equals、hashCode、toString、clone 和 finalize,这些方法都有通用的约定,需要在子类中被覆盖(override)。如果不遵守这些约定,依赖这些约定的...
在重写 equals() 方法时,需要遵守通用约定,包括: 1. 自反性:对于任意的引用值 x,x.equals(x) 一定为 true。 2. 对称性:对于任意的引用值 x 和 y,当 x.equals(y) 返回 true 时,y.equals(x) 也一定返回 true...
在Java编程语言中,`equals()`方法和`==`运算符是两个经常用来比较对象的...同时,为了确保其他自定义类的`equals()`方法正确实现,应遵循通用约定,即同时重写`equals()`和`hashCode()`方法,以保持一致性和正确性。
在Java编程中,`equals`方法是用于比较两个对象是否相等的重要方法。...遵循通用约定和同时更新`hashCode`方法能确保一致性和正确性。通过理解和实践这些原则,开发者可以创建出更可靠、更具可维护性的Java应用程序。
遵循 `equals()` 方法的通用约定可以帮助开发人员编写出更加健壮和易于维护的代码。此外,理解何时以及如何重写 `equals()` 方法对于创建高质量的Java应用程序至关重要。通过遵循上述指导原则,可以确保在实际应用中...
- **项03:覆盖equals时请遵守通用约定**:正确的equals方法实现对于确保对象一致性至关重要。 #### 代码设计原则 - **项04:始终覆盖hashCode**:当重写了equals方法时,必须同时重写hashCode方法以保持一致性。 ...
10. **R10:同时定义equals()和hashCode()方法** - 如果重写了`equals()`方法,则也应该重写`hashCode()`方法。 - 这样可以确保当两个对象相等时,它们具有相同的哈希码。 11. **R11:添加新字段时重新定义equals...
根据给定的文件信息,以下是对“core java...Object是所有Java类的根类,提供了如toString()、equals()、hashCode()等基础方法,用于支持对象的基本操作。理解并适当重写这些方法对于编写高质量的Java代码至关重要。
2. **基本方法实现**:为通用目的创建的类,应包含`equals()`、`hashCode()`、`toString()`、`clone()`(实现`Cloneable`)和`Serializable`接口,以提供标准的行为。 3. **测试代码**:每个类都应该有一个`main()`...
**Java中的Object类**:在Java中,所有类都直接或间接地继承自Object类,它提供了所有Java对象通用的行为,如toString()、equals()和hashCode()等方法。通过继承,我们可以为特定类添加额外的功能,同时保持与Java...
集合处理部分提供了处理集合时的建议,如避免null元素、正确使用equals()和hashCode()等。并发处理部分讲述了多线程编程中的最佳实践,包括锁的使用、线程安全的变量等。控制语句的规约指导如何有效使用if、for、...
变量和方法名使用小驼峰命名法,如`myVariableName`;常量全大写,单词间用下划线分隔,如`MY_CONSTANT`。 2. **注释**:良好的注释能够帮助他人理解代码。类注释通常描述类的功能和用途,方法注释解释方法的作用和...
- 重写`equals()`和`hashCode()`方法时,确保满足对象相等性的约定。 - 尽可能使用接口而非具体类进行类型声明,提高代码的灵活性。 【开发EJB规则】 - 遵守Enterprise JavaBeans(EJB)的官方规范,如实体Bean、...
2. **基础方法**:为通用类提供`equals()`、`hashCode()`、`toString()`、`clone()`(实现`Cloneable`)和`Serializable`接口,以支持基本操作和序列化。 3. **测试代码**:为每个自定义类创建一个`main()`方法,...
- 创建通用类时,应包含常用的方法:`equals()`、`hashCode()`、`toString()`、`clone()`(实现`Cloneable`)和`Serializable`接口。 3. **测试代码**: - 为每个类提供一个`main()`方法用于测试,方便检查和验证...
2. **常规类设计**:创建通用类时,包括`equals()`、`hashCode()`、`toString()`、`clone()`(实现`Cloneable`)和`Serializable`接口。这些方法提供了基本的对象操作和比较。 3. **测试代码**:每个类都应该有一个...
为了确保对象的正确比较和操作,应实现`equals()`, `hashCode()`, `toString()`等方法。如果类实现了`Cloneable`接口,还需提供`clone()`方法;若要序列化对象,则需实现`Serializable`接口。这些方法的正确实现对于...