1. 前言
hashCode方法在Java集合框架中扮演了重要角色,它不仅提供了快速查找和比较对象的一种手段,还保证了集合中对象存储和操作的正确性和高效性。理解和正确实现hashCode方法是Java开发中不可或缺的基础知识之一。
2. 问题分析
然而,我一直理解的hashcode()只是获取内存中的地址值,就在昨天做了一个小测试,我就很懵,就到处搜集资料,发现我从一开始对地址值的理解就有误。
public static void main(String[] args) {
Student s = new Student("小明",18);
Student A1 = new Student("小明",18);
System.out.println(s);//demo.Student@165f3d4
System.out.println(A1);//demo.Student@165f3d4
System.out.println(s.hashCode() == A1.hashCode());//true
System.out.println(s == A1);//false
}
在我所学的资料和老师们都在说,打印对象打印的是地址值,然而我这个测试,打印出的s和A1内容完全一样,但使用 == 号却返回的是false,然后我就很不解出现了很多疑惑。
3. 问题解答
其实直接打印对象并不是地址值!!!
例如:s的对象,demo.Student@165f3d4
- demo.Student:全类名,默认包名.类名
- @:分隔符
- Student:计算出的hashcode值,也就是s.hashCode()返回的值
地址值:地址值是指对象在内存中的实际存储位置,也就是对象在计算机内存中的物理地址。
那为什么老师经常说是,打印对象打印的是对象的地址值呢?
我觉得是为了帮助我们理解,因为Object类的hashCode()方法,默认就是通过地址值进行计算的,其实不重写,这一点是对的。但是重写就会出现,我明明new 出来两块内容,但是打印对象是相同的,这主要是因为我们重写了,hashcode他是通过每个内容进行计算hashCode的值,然后求和进行返回的。
注意:在Java中,三个连续的句点(...)在方法参数声明中表示可变长度参数(Varargs)。这种语法允许方法接受数量可变的参数。
show("18",1,"nihao","帅哥");
private static void show(Object... value) {
Object[] value1 = value;
String string = Arrays.toString(value1);
System.out.println(string);
}
4. 总结
-
重写hashCode方法:在Java中,hashCode方法不是直接返回对象的内存地址,而是根据对象的内容计算出的一个哈希码(hash code)。这个哈希码用于在集合类中确定对象在内存中的存储位置,以及在进行查找和比较时的效率。
-
对象打印:对象的打印形式如 "demo.Student@165f3d4" 并不是对象的地址值,而是由类名、'@'符号和hashCode值组成的字符串表示。默认情况下,Object类的toString方法返回的就是类名@hashCode的形式。
-
hashCode和equals的关系:在重写了hashCode方法的情况下,相等的对象(即equals方法返回true的对象)应该具有相同的hashCode值。这是为了保证在使用集合类(如HashMap、HashSet等)时能够正确地存储和查找对象。
- 不重写hashCode可以想象成打印的就是对象存储在内存中的地址值。
- 重写就是根据内容存放在内存的地址值进行累加。