Java基础>16 - Object类、toString、equals、hashCode 方法、equals与==的区别

学习总结:
链接:【Java基础、springboot、springcloud、docker 等,学习目录

Object 类:

Object 类是所有类的终极父类,任何一个类都继承了 Object 类(包括自定义的类),接口不能继承Object,只有一个无参的构造。常用方法:toString()、equals()、hashCode()

一、toString() 方法:

返回对象的描述信息:全类名@哈希码值的十六进制形式

System.out.println(new User().toString());
// 直接传入对象的时候会默认调用对象继承自Object类的 toString() 方法
// System.out.println(new User());
// com.coolron.user.domain.User@7f63425a

toString()方法的使用:
一般在定义对象的时候会重写Object类的 toString() 方法,按照我们需要的数据格式输出。

public class User {
    private String id;
    private String username;
    private String password;
    @Override
    public String toString() {
        return "User{" +
                "id='" + id + '\'' +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}
System.out.println(new User().toString());
// User{id='null', username='null', password='null'}

编程规范:开发者要对自定义的类重写toString(),对对象做详细的说明

二、equals() 方法:

默认比较的是两个对象的内存值,相等返回 true,否则 false。可重写equals方法。
问题:既然equals比较的是对象的内存值,那我们在开发的时候经常使用 equals() 方法比较两个字符串是否相等,为什么?
答案: String 重写了Object类的equals方法,比较的是字符串内容是否相等。

// String 类重写了 equals方法
public boolean equals(Object var1) {
    if (this == var1) {
        return true;
    } else {
        if (var1 instanceof String) {
            String var2 = (String)var1;
            int var3 = this.value.length;
            if (var3 == var2.value.length) {
                char[] var4 = this.value;
                char[] var5 = var2.value;

                for(int var6 = 0; var3-- != 0; ++var6) {
                    if (var4[var6] != var5[var6]) {
                        return false;
                    }
                }
                return true;
            }
        }
        return false;
    }
}
三、hashCode() 方法:

返回该对象的哈希码值,int类型,同一个对象的哈希码值是唯一的。java规定如果两个对象equals返回true,那么这两个对象的hashCode码必须一致。
规范: 一般重写了类的equals方法后,都会重写它的hashCode方法。

String str1 = new String("Ron");
String str2 = new String("Ron");

System.out.println(str1.hashCode()); // 82353  
System.out.println(str2.hashCode()); // 82353 String 重写了hashCode 方法,所以两个对象的哈希值相等
System.out.println(new Test().hashCode()); // 963269035
System.out.println(new Test().hashCode()); // 1359484306  Test 为自定义的类,没有重写hashCode,返回的是对象的哈希值
四、面试题:
1、equals 和 == 的区别:

==:
a、比较基本数据类型,比较的是值是否相等。
b、比较引用数据类型,比较的是地址是否相等。
equals:
a、没有重写,比较的是两个对象的地址值是否相等。此时等价 ==。
b、重写后按照重写后的方式比较。
比较引用数据类型:

 // 注意 String类重写了equals 方法
 String str1 = "Hello";
 String str5 = "Hello";
 String str2 = new String("Hello");
 String str4 = new String("Hello");
 String str3 = str2; // 引用传递,同一对象
 System.out.println(str1 == str2); // false(str2是new的一个新地址)
 System.out.println(str1 == str3); // false(str3和str2内存地址一样,和str1地址不同)
 System.out.println(str2 == str3); // true(引用str2,地址相同)
 System.out.println(str1 == str5); // true(String作为基本类型,没创建新地址)
 System.out.println(str4 == str2); // false(内存地址不同)
 System.out.println(str1.equals(str2)); // true(内容一致,都是“hello”)
 System.out.println(str1.equals(str3)); // true(内容一致,都是“hello”)
 System.out.println(str2.equals(str3)); // true(内容一致,都是“hello”)
 System.out.println(str2.equals(str4)); // true(内容一致,都是“hello”)
 System.out.println(str1.equals(str5)); // true(内容一致,都是“hello”)

比较基本数据类型:

    public static void main(String[] args) {
        Integer a = 1;
        boolean equals = a.equals(1);
        System.out.println(equals);  // true
    }
    
    // Integer 中对equals 重写:部分源码
    private final int value;
    public Integer(int value) {
        this.value = value;
    }
    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }
2、equals 和 hashCode 方法的关系(参考互联网):

a、作用: 都是用于比较java对象是否一致。
equals:重写的equal() 方法里一般比较全面、复杂,效率低。
hashCode:生成一个int类型的hash值。效率高,但hash值可能不唯一。
b、问题: 由于hash值的生成问题,可能导致不同的对象,hash值相同。
c、结论:
1.equal()相等的两个对象他们的hashCode()肯定相等,也就是用equal()对比是绝对可靠的。
2.hashCode()相等的两个对象他们的equal()不一定相等,也就是hashCode()不是绝对可靠的。
d、使用:
所有对于需要大量并且快速的对比的话如果都用equal()去做显然效率太低,所以解决方式是,每当需要对比的时候,首先用hashCode()去对比,如果hashCode()不一样,则表示这两个对象肯定不相等(也就是不必再用equal()去再对比了),如果hashCode()相同,此时再对比他们的equal(),如果equal()也相同,则表示这两个对象是真的相同了,这样既能大大提高了效率也保证了对比的绝对正确性!

这种大量的并且快速的对象对比一般使用的hash容器中,比如hashset,hashmap,hashtable等等,比如hashset里要求对象不能重复,则他内部必然要对添加进去的每个对象进行对比,而他的对比规则就是像上面说的那样,先hashCode(),如果hashCode()相同,再用equal()验证,如果hashCode()都不同,则肯定不同,这样对比的效率就很高了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值