java中的equals()和hashcode()方法总结

本文详细解析了Java集合框架中equals方法和hashcode方法的作用与实现原理,探讨了它们如何帮助提高Set和Map集合操作效率。

前言:
在java集合框架中,常用的集合接口有List,Set,Map,其中List是有序可以重复的,Set是无序不可重复的,Map是键值对,并且Map的key值也是不可重复的,那么怎么判断set集合中添加的元素,以及Map集合中的Key值是否重复呢?这里就用到了equals和hashcode这两个方法,先来了解下这两个方法

1.equals()方法
equals是根类Object的方法,源码如下:

public boolean equals(Object obj) {
    return (this == obj);
}

equals方法是比较的对象的表面,不是比较jvm中的存放地址,比如string类中重写equals方法
在String类中,它比较的就是字符串是否相同,若相同就返回true,不同则返回false

public static void main(String[] args) {
    String str1="qwe";
    String str2="qwe";
    String str3=new String("qwe");

    System.out.println(str1.equals(str2)); //true
    System.out.println(str1.equals(str3));//true
}

那如果我们用“==”来比较,结果就不一样了,见代码

public static void main(String[] args) {
    String str1="qwe";
    String str2="qwe";
    String str3=new String("qwe");

    System.out.println(str1==str2); //true
    System.out.println(str1==str3);//false
}

“==”比较的是地址而不是字符串,str1,str2,指向同一个常量,是同一个地址,所以返回true,而str3是新new出来的一个对象,在堆中开辟了新的内存,所以地址就不一样,返回false

2.hashcode()方法
同上面的equals方法,hashcode也是根类Object的方法
以下解释来自JKD1.6 API
hashcode方法是返回对象的哈希码值。
在java应用程序执行期间,在对同一个对象多次调用hashcode方法时,必须一致地返回相同的整数,前提是将对象进行equals比较时所用的信息没有被修改
如果根据equals方法,比较两个对象是相等的,那么对于这两个对象调用hashcode方法必须生成相同的整数结果

public static void main(String[] args) {
    String str1="qwe";
    String str2="qwe";
    String str3=new String("qwe");

    System.out.println(str1.hashCode());//112383
    System.out.println(str2.hashCode());//112383
    System.out.println(str3.hashCode());//112383
}

由上我们可以得出以下三点:
1. hashcode返回的是int类型的数字
2. equals方法判断返回false的两个对象,hashcode可能相同
3. equals方法判断返回true的两个对象,hashcode一定相同
回到一开始的问题,在Map集合中,我们判断Map中Key值是否相同,即是否已经存在这个Key值是,我们需要进行遍历,遍历所有Map中元素的Key值,与之进行比较,如果我们Map集合中有1000个元素,我们可能需要使用1000次equals方法进行比较,当然也不排除我遍历到第三个就发现有重复,然后遍历结束,但是如果一直遍历到999才发现重复这就相当的耗时了,这是就需要使用hashcode和equals方法了。
当往集合里添加元素的时候,使用hashcode方法直接把它放在指定的位置,如果这个位置是空的就直接把它放上去,如果已经存在其他的元素,就进行equals比较,这就极大的减低了equals使用频率,比较结果如果相同,就不需要存放了,如果不同就连接到已经存在的元素后面,Set集合也同理

在Map集合中,如果你添加元素的时候,添加相同的Key值,就会覆盖之前对应的Object,比如:

public static void main(String[] args) {
    Map map=new HashMap();
    map.put("001", "qaz");
    map.put("002", "wsx");
    map.put("001", "edc");
    System.out.println(map.size());//2
    System.out.println(map.get("001"));//edc
}

但是,不同的Key值可以对应相同的Object,如下

public static void main(String[] args) {
    Map map=new HashMap();
    map.put("001", "qaz");
    map.put("002", "qaz");

    System.out.println(map.size());//2
    System.out.println(map.get("001").equals(map.get("002")));//true
    System.out.println(map.get("001").hashCode());//111722
    System.out.println(map.get("002").hashCode());//111722
}

需要注意的是:在类中如果你要重写hashcode方法,那也需要重写equals方法

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值