java 的数据类型分为“基本数据类型” 和“引用数据类型”:
---》在基本数据类型的比较中,== 比的就是基本数据类型变量中所保存的值。
---》在引用数据类型的比较中,== 才比较的是变量所指向的对象的地址。
hashCode()返回该对象的哈希码值,该值通常是一个由该对象的内部地址转换而来的整数,它的实现主要是为了提高哈希表。
我们以引用数据类型为例,因为基本类型比较的是值,简单无须多言。
封装好的String 类型为例:
(注意:ObjectL中有方法equals, hashcode() ,所有其他类都会继承这两个方法)。
public class hei { public static void main(String[] args) { String n1 = "sd"; //常量池字符串sd String n2 = "sd"; //常量池字符串sd String n3 = new String("sd"); //新对象sd String n4 = new String("sd"); //另一个对象sd System.out.println(n1.hashCode()); System.out.println(n2.hashCode()); System.out.println(n3.hashCode()); System.out.print("n1与N2 是否相=="); System.out.println(n1 == n2); System.out.print("N1 N2 EQUALS 比较: "); System.out.println(n1.equals(n2)); System.out.print("n2与N3 是否相=="); System.out.println(n2 == n3); System.out.print("N2 N3 EQUALS比较"); System.out.println(n2.equals(n3)); System.out.print("N3 N4 EQUALS比较"); System.out.println(n3.equals(n4)); /* * ==操作比较的是两个变量的值是否相等, 对于引用型变量表示的是两个变量在堆中存储的地址是否相同, 即栈中的内容是否相同。 * equals操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。 */ } }
这个测试例子中,有N1到N4 4个字符串:
(1)首先看N1与N2 这两个都是直接量,也就是N1放入“sd”在常量池中,常量池中有了一个对象"sd",
当 String n2 = "sd"; 执行的时候, 系统会查找常量池,找到了"sd",就把N2指向常量池的对象“sd”中,实际上N1 N2指向的是同一个对象。(所以地址相同,对象也相同,当然内容也相同了)。
(2) N3 N4是通过NEW创建的对象,所以不会在常量池中,而是新建一个对象。所以N3 N4 指向的地址不同,这里必须知道的是,
N3 N4 存放于内存的栈中,N3 N4 的内容分别是堆中对象的地址,是不同的。
所以N3 == N4 是false ,因为== 比较的是内存地址
同理 N2 == N3 也是false。
N3.equals(N4) 是true ,因为String重写了equals()方法,如下:
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String) anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }
从中我们可以看出,String 类重写了equals方法使其比较了字符串内容。 而Object中的equals方法比较的是地址。
如下: Oject中的equals()
public boolean equals(Object obj) {
return (this == obj);
}
至于hashcode() ,这个整型值是用在集合框架中的,目的就是快速搜索。 --摘自网络
由于集合set要求元素不重复,所以每次插入的时候需要进行确认有没有重复,如果元素有1万个,需要1万次的equals那么效率很慢很慢。 hashCode方法实 际上返回的就是与对象内存地址有关的一个数值。 这样一来,当集合要添加新的元素时,先调用这个元素的hashCode方法,就一下子能定位到它应该放置的物理位置上。如果这个位置上没有元素,它就可以 直接存储在这个位置 上,不用再进行任何比较了;如果这个位置上已经有元素了,就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址。所以这里存在一个冲突解 决的问题。这样一来实际调用equals方法的次数就大大降低了,几乎只需要一两次。 所以,Java对于eqauls方法和hashCode方法是这样规定的: 1、如果两个对象相同,那么它们的hashCode值一定要相同; 2、如果两个对象的hashCode相同,它们并不一定相同 上面说的对象相同指的是用eqauls方法比较。