Object 类是 Java 中所有类的始祖, 在 Java 中每个类都是由它扩展而来的,所以可以使用 Object 类型的变量引用任何类型的对象。
1、equals方法
== 和 equals()的区别:
对于基本数据类型,==比较的是值是否相等,对于因引用数据而言,则比较的是引用的地址
Object中的equals()方法比较的是引用数据类型变量所指的地址是否相等,且无法用于比较基本数据类型(因为equals是对象的方法,基本数据类型不是对象)
但是,equals()的方法在比较String类型时,因为String类型的字符串存储在字符串常量池中,当其字符串相同时,在字符串常量池中的位置地址也相同,所以会返回true,其实是String当中的equals()重写了Object()方法当中的equals(),String当中的equals()会先比较变量比较的地址是否相等,若相等则结束,否则就会直接逐个比较字符串的值
- public class Person {
- public int age;
-
- public Person(int age) {
- this.age = age;
- }
- }
-
- public class Test{
- public static void main(String[] args) {
- int a = 18;
- int b = 18;
- System.out.println(a=b); //返回true,因为此时比较的是数值
-
- Person p1 = new Person(18);
- Person p2 = new Person(18);
- System.out.println(p1 == p2); //返回false,此时比较的是地址
- System.out.println(p1.equals(p2)); //返回false,因为两个对象地址不同
-
- String a = new String("123");
- String b = new String("123");
- System.out.println(a.equals(b)); //返回true,因为String重写了equals方法
- }
- }
2、HashSet hashCode
HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合。
它会将传进去的对象转换为一个int类型的数值,如果如果转换完之后,有其他数值与其相等,则抛弃,这样就达到了去重,而将对象转换为哈希值(int类型)就是hashCode来实现的
- HashSet hashSet = new HashSet();
- hashSet.add(1);
- hashSet.add(1);
- sout(hashSet); //只会输出一个1
HashSet 允许有 null 值。
HashSet 是无序的,即不会记录插入的顺序。
hashCode是一个本地方法,用C++来实现的,HashSet的最后就是通过hashCode来完成的,它既可以实现对引用数据类型的判断,亦可以实现对基本数据类型的判断
3、为什么重写equals后,必须重写hashCode方法?
在不重写equals时,使用equals进行比较时,若地址不同(不是相同的对象)则返回false,然后我们同时调用hashCode,因为hashCode会将不同类型的变量(包括对象)转换为int类型的数据,所以hashCode也会返回false,但是,我们重写equals方法,用一个例子来表示:
- //先定义一个Person类
- public class Person {
- public int age;
-
- public Person(int age) {
- this.age = age;
- }
-
- //重写equals方法,比较对象中的属性值
- public boolean equals(Person anP){
- if(this.age == anP.age){
- return true;
- }
- return false;
- }
- }
-
-
- public class Test {
- public static void main(String[] args) {
- Person p1 = new Person(18);
- Person p2 = new Person(18);
-
- System.out.println(p1.equals(p2)); //true
-
- HashSet hashSet = new HashSet();
- hashSet.add(p1);
- hashSet.add(p2);
- System.out.println(hashSet); //两个内容,说明对象不同
- }
- }
我们来看,我们重写了equals方法,使其比较的是对象中的具体值,例子中返回true是完全正确的,即使他们不是同一个对象,但是我们再用HashSet来存放两个对象时,很显然会出现两个内容,这也是完全正确的,但是,我们觉得没问题是因为我们知道程序对equals进行了重写,所以不同对象返回的也是true,但是使用者可不一定知道,当不知情的人看到调用equals返回的是true时,他们会觉得这两个对象相同,然后放到HashSet中之后却有两个元素,这就会产生矛盾,弄不清楚了。所以,重写equals方法时必须一并重写hashCode方法