判断Set里的元素是否重复、==、equals、hashCode方法研究-代码演示
被测试类,没有重写hasCode()和equals()方法:
package niukewang; import java.util.Objects; public class setClass { String a;
String b;
public setClass(String a, String b)
{
this.a=a;
this.b=b;
}
}
测试类:
package niukewang; import java.util.HashSet;
import java.util.Set; public class test1 { public static void main(String args[])
{
setClass s1=new setClass("http://www.yjbys.com/", "");
setClass s2=new setClass("http://www.yjbys.com/", "");
setClass s3=new setClass("http://www.yjbys.com/", ""); Set<setClass> set=new HashSet<>();
set.add(s1);
set.add(s2);
set.add(s3); String ss=new String("Hello");
String ss1=new String("Hello");
System.out.println(ss==ss1);
System.out.println(ss.equals(ss1));
System.out.println(ss.hashCode()==ss1.hashCode()); System.out.println("set...."); System.out.println(s1==s2);
System.out.println(s1.equals(s2));
System.out.println(s1.hashCode()==s2.hashCode());
System.out.println("Number is "+set.size());
}
}
输出结果:
false (string不是同一个对象)
true (只要值相同就行了)
true (hashcode也相同)
set....
false (不是同一个对象)
false
false
Number is 2
这是没有覆盖hashCode()和equals()方法的情况。
被测试类覆盖hashCode()和equals()方法:
package niukewang; import java.util.Objects; public class setClass { String a;
String b;
public setClass(String a, String b)
{
this.a=a;
this.b=b;
} public int hashCode() {
return a.hashCode();
} public boolean equals(Object obj)
{
if(obj==null) return false; if(getClass() != obj.getClass()) return false; final setClass s=(setClass)obj; return Objects.equals(this.a, s.a);
}
}
覆盖之后,hascode的值就是设置的a的hashcode,equals()比较的也是a的hashcode的值。
测试结果输出:
false
true
true
set....
false
true
true
Number is 1
set内部实现实际是map,在处理map的key的时候调用了hashcode方法,HashMap中有代码如下
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
调试证明:把元素往set中添加时,首先会对比hashcode是否相等,如果hashcode不相等就直接往set中加这个元素,如果 hashcode相等就对比equals方法,如果equals不相等就往set中加这个元素,所以set的元素重复性是根据hashcode和 equals方法来判断的,
对于为什么覆盖equals方法就一定要覆盖hashcode方法的原因也显示了出来:由于是先调用hashcode方法的,如果不覆盖hashcode 方法,默认会去取内存的物理地址作为生成hashcode的依据,那么两个不同的对象的hashcode必然不同的,于是直接结束添加了,根本没法调用到 equals方法,就不用说equals内部实现如何了,不管equals是返回true还是false都没机会调用到了。
由于set内部是用map实现的,所以往map中put元素的时候是一样的原理。
证明如果不重写hashcode方法,无论equals是返回true还是返回false都没有用,因为在调用equals方法之前会先调用hashcode方法,在调用hashcode方法的时候
就已经被认为这些对象全部是不重复的元素,直接往set中添加这些对象,并完成添加,equals方法就没有机会调用到。
借鉴博文:http://www.cnblogs.com/langtianya/p/4421582.html
判断Set里的元素是否重复、==、equals、hashCode方法研究-代码演示的更多相关文章
- equals(),hashcode()方法详解
Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要重写这两个方法,今天就来介绍一些这两个方法的作用. equals ...
- Java判断一个字符是否是数字的几种方法的代码
在工作期间,将写内容过程经常用到的一些内容段做个记录,下面内容是关于Java判断一个字符是否是数字的几种方法的内容,希望能对码农们有好处. public class Test{ public stat ...
- 面试官:HashSet如何保证元素不重复?
本文已收录<Java常见面试题>系列,Git 开源地址:https://gitee.com/mydb/interview HashSet 实现了 Set 接口,由哈希表(实际是 HashM ...
- 如何编写出高质量的 equals 和 hashcode 方法?
什么是 equals 和 hashcode 方法? 这要从 Object 类开始说起,我们知道 Object 类是 Java 的超类,每个类都直接或者间接的继承了 Object 类,在 Object ...
- Effective Java 第三版——11. 重写equals方法时同时也要重写hashcode方法
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- java中的 equals + hashCode
[0]README 0.1)本文转自 core java volume 1, 旨在理清 equals + hashCode方法: [1]equals方法 1.1) Object中的 equals 方法 ...
- 批量插入数据, 将DataTable里的数据批量写入数据库的方法
大量数据导入操作, 也就是直接将DataTable里的内容写入到数据库 通用方法: 拼接Insert语句, 好土鳖 1. MS Sql Server: 使用SqlBulkCopy 2. MySql ...
- JavaSE的包装类,自动装箱和自动拆箱 ,字符窜转换,toString(),equals(), hashCode()的区别
一.基本数据类型和包装类 包装类均位于Java.lang包,包装类和基本数据类型的对应关系如下表所示: Primitive-Type Wrapper-Class byte ...
- equals(),hashcode(),克隆学习心得
equals(),hashcode(),克隆学习心得 其实在开发时候,很少去重写equals(),hashCode()方法,但是有些时候业务需要还是要重写. 注意: 重写equals()方法一定要重写 ...
随机推荐
- 边工作边刷题:70天一遍leetcode: day 85-3
Zigzag Iterator 要点: 实际不是zigzag而是纵向访问 这题可以扩展到k个list,也可以扩展到只给iterator而不给list.结构上没什么区别,iterator的hasNext ...
- 首次安装Pycharm出现No Python interpreter selected解决方法
刚装完Pycharm,新建Project的时候,出现了No Python interpreter selected.网上的教程里path interpret栏里应该选中python.exe,但是我搜遍 ...
- usb驱动开发3之先看core
上节中看到usb目录中有一个core目录,凡是认识这个core单词的人都会想要先看看它是什么,对不?用LDD3中一幅图,来表述usb core所处地位. usb core负责实现一些核心的功能,为别的 ...
- Oracle异常处理,动态游标
小例子,方便以后查阅. 包头需要声明: type C_CURSOR is ref cursor; procedure visitcount(in_date number, out_code out ...
- .net 4.0 自定义本地缓存策略的不同实现
在分布式系统的开发中,为了提高系统运行性能,我们从服务器中获取的数据需要缓存在本地,以便下次使用,而不用从服务器中重复获取,有同学可能要问,为什么不使用 分布式缓存等,注意,服务器端肯定是考虑到扩展, ...
- C语言 文件操作11--文件函数再讲 fseek()和ftell()
//文件函数再讲 //fseek(),ftell(), #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdl ...
- [tomcat7源码学习]初始化之catalina.home和catalina.base(转)
我们在代码中为了获取某个配置文件路径下的文件经常会这么写 String tomcatPath = System.getProperty("catalina.home") + &qu ...
- ibatis动态查询条件
ibatis的调试相对困难,出错的时候主要依据是log4生成的log文件和出错提示,这方面要能比较熟练的看懂. 下面这个配置基本上包含了最复杂的功能:分页\搜索\排序\缓存\传值Hash表\返回has ...
- 那些年我们写过的T-SQL(下篇)(转)
原文:http://www.cnblogs.com/wanliwang01/p/TSQL_Base04.html 下篇的内容很多都会在工作中用到,尤其是可编程对象,那些年我们写过的存储过程,有木有 ...
- python数字图像处理(1):环境安装与配置
一提到数字图像处理编程,可能大多数人就会想到matlab,但matlab也有自身的缺点: 1.不开源,价格贵 2.软件容量大.一般3G以上,高版本甚至达5G以上. 3.只能做研究,不易转化成软件. 因 ...