为什么重写 equals 还要重写 hashcode?
在 Java 中,hashCode() 方法和 equals() 方法是紧密相关的,如果重写了 equals() 方法,就应该同时重写 hashCode() 方法,这是因为:
hashCode()方法和equals()方法是用于判断对象是否相等的两个方法,而这两个方法的返回值必须一致。如果两个对象相等,它们的hashCode()方法必须返回相同的值,否则会导致在使用哈希表等数据结构时出现错误。- 在 Java 中,哈希表等数据结构是基于哈希值进行快速查找的。当我们需要使用哈希表等数据结构时,需要将对象放入哈希表中,此时会使用对象的
hashCode()方法计算出哈希值,然后根据哈希值将对象放置到相应的位置上。如果两个对象相等,但是它们的hashCode()方法返回的值不同,那么就会导致在哈希表中无法正确地查找到对象。
因此,当我们重写了 equals() 方法时,也必须重写 hashCode() 方法,以确保两个方法的返回值一致,从而保证对象在使用哈希表等数据结构时能够正确地工作。
== 和 equals 比较的区别
==比较的是两个对象的内存地址,判断它们是否指向同一个对象。如果两个对象的内存地址相同,即它们是同一个对象,那么==返回true,否则返回false。equals()比较的是两个对象的内容是否相等。默认情况下,equals()方法使用的是==比较,也就是比较两个对象的内存地址是否相同。但是可以通过重写equals()方法来改变比较的方式,例如比较两个对象的属性是否相同。==是一个操作符,可以用于比较任何两个类型的变量,而equals()是一个方法,只能用于比较实现了该方法的类的对象。
因此,== 和 equals() 比较的方式不同,适用的场景也不同。如果需要比较两个对象是否是同一个对象,应该使用 == 操作符;如果需要比较两个对象的内容是否相等,应该使用 equals() 方法。在使用 equals() 方法时,需要注意重写该方法,以确保比较的方式符合自己的需求。
为啥有时会出现 4.0 - 3.6 = 0.40000001 这种现象?
这种现象是由于浮点数的精度问题导致的。在计算机中,浮点数的实现采用二进制浮点数表示法,由于二进制浮点数无法精确地表示某些十进制分数,因此在进行浮点数计算时可能会出现精度损失的情况。
例如,在十进制下,0.1 可以精确地表示为 1/10,但是在二进制下无法精确地表示为有限的二进制小数。因此,0.1 在二进制浮点数表示法中被近似为一个无限循环的二进制小数 0.0001100110011001100110011001100110011001100110011...,这个二进制小数的精度是有限的,因此在进行浮点数计算时可能会出现精度损失的情况。
在计算机中,浮点数的精度损失可能会导致一些计算结果不是精确的实数,而是一个近似值。例如,4.0 - 3.6 在计算机中的计算结果可能是 0.40000001,而不是精确的 0.4。这种精度损失的情况在浮点数计算中比较常见,需要在编程时注意避免或减少其影响。
final 关键字的作用
在 Java 中,final 是一个关键字,它可以用来修饰类、变量和方法,其作用如下:
- 修饰类:如果一个类被声明为
final,则该类不能被继承,也就是说不能有子类。这种情况通常出现在一些基础类库中,例如java.lang.String和java.lang.Integer等。 - 修饰变量:如果一个变量被声明为
final,则该变量的值不能被修改,也就是说它是只读的常量。这种情况通常出现在一些常量定义中,例如 `public static final int MAX_VALUE = 100;。 - 修饰方法:如果一个方法被声明为
final,则该方法不能被子类重写,也就是说它是不可变的。这种情况通常出现在一些安全性要求高的类库中,例如java.lang.Object中的wait()和notify()等。
总的来说,final 关键字的作用就是为了保证代码的安全性和稳定性。通过将类、变量和方法声明为 final,可以避免在继承、修改和调用时出现不必要的错误和问题,从而提高程序的可靠性和可维护性。