上一篇地址:赶紧收藏!2024 年最常见 100 道 Java基础面试题(一)-CSDN博客
三、hashCode()
相同,是否意味着equals()
也一定为true
?
在Java中,hashCode()
和equals()
是两个常用方法,它们在对象的比较和散列数据结构(如HashMap
)中扮演着重要角色。
hashCode()
方法:
hashCode()
方法定义在java.lang.Object
类中,返回一个int
类型的值,这个值是对象的哈希码,也就是一个代表对象的整数值。- 在Java中,如果两个对象通过
equals()
方法比较是相等的,那么这两个对象的hashCode()
方法返回的结果也必须相同,以保证在散列数据结构中的一致性。 hashCode()
方法被用来在散列数据结构中定位对象,因此它对于性能有重要影响。一个好的哈希函数应该尽量分散对象的哈希码,以减少哈希冲突。
equals()
方法:
equals()
方法同样定义在java.lang.Object
类中,用于比较两个对象是否等价或相同。- 默认情况下,
equals()
方法比较对象的引用,即检查两个对象是否为同一实例。但是,通常需要重写此方法以提供更深层的比较逻辑,例如比较对象的内容。 - 当重写
equals()
方法时,也应该重写hashCode()
方法,以保持两者之间的一致性,即如果两个对象通过equals()
比较是相等的,那么它们的hashCode()
方法也必须返回相同的值。
hashCode()
与equals()
的一致性原则:
- 等价性:如果两个对象通过
equals()
比较是相等的,那么这两个对象调用hashCode()
方法也必须产生相同的整数结果。 - 一致性:在Java应用程序执行期间,只要对象的equals比较所用的信息没有被修改,那么对于同一个对象多次调用
hashCode()
方法必须始终返回相同的值。 - 非等价性:如果两个对象通过
equals()
比较是不等价的,那么这两个对象调用hashCode()
方法不一定要产生不同的整数结果,但是通常会产生不同的结果,以提高散列数据结构的性能。
第三题的答案:
- 如果两个对象的
hashCode()
相同,并不意味着它们通过equals()
比较也会是相等的。hashCode()
相同的对象可能相等,也可能不相等。 hashCode()
用于散列,而equals()
用于比较逻辑等价性。在重写equals()
方法时,通常也需要重写hashCode()
方法,以保持一致性。
在实际编程中,正确地实现hashCode()
和equals()
方法对于确保对象的正确比较和在散列集合中的适当行为至关重要。
四、final关键字
在Java中有什么作用?
final
关键字在Java语言中有多种用途,主要包括:
修饰变量:当final
用于修饰变量时,该变量变成了常量。常量的值在初始化后不能被改变。如果常量是对象引用,则不能指向其他对象,但对象内部的状态可以改变(除非对象本身是不可变的)。常量名通常使用全大写字母表示。
final int MAX_COUNT = 10; // 整数值常量
String username = "Kimi"; // 字符串常量
final MyClass obj = new MyClass(); // 对象引用常量,但不能重新指向另一个对象
修饰方法:将方法声明为final
可以防止该方法被重写。这意味着子类无法覆盖该方法。这通常用于那些设计为不可改变的行为。
public final void someMethod() {
// 方法体
}
修饰类:将类声明为final
意味着这个类不能被继承。没有其他类可以成为这个类的子类。
public final class UtilityClass {
// 类体
}
局部变量:虽然不常见,但final
也可以用于修饰局部变量,这表示该变量在初始化后不能被重新赋值。
void testMethod() {
final int value = 5;
// value = 10; // 这将导致编译错误,因为value是final的
}
匿名类和 lambda 表达式:在使用匿名类或lambda表达式时,通常隐式地将其中的变量作为final
处理,因为它们在匿名类或lambda表达式的作用域内是不可变的。
Thread thread = new Thread(finalRunnable); // finalRunnable 是一个final变量
泛型:在泛型中,使用final
关键字可以防止对泛型类型进行子类化,这有助于避免类型擦除带来的问题。
Map<String, List<final String>> map = new HashMap<>();
总结:
final
关键字用于保证变量值的不变性,方法的不可重写性,以及类的不可继承性。- 在实际编程中,合理使用
final
可以提高程序的安全性和可读性,并且有助于编写出更稳定、更易于维护的代码。