JAVA学习-序号2 HashSet初入门,hashCode和equals方法
来源:互联网 发布:会员视频源码 编辑:程序博客网 时间:2024/06/02 02:36
今天学习的是Collection中的foreach遍历,Set集合的基本特点,以及HashSet初入门。
示例代码如下:
import java.util.HashSet;import java.util.Set;public class TestSet { public static void main(String[] args) { Set books=new HashSet(); //添加一个字符串对象 books.add(new String("Struts")); //再次添加相同字符串,因俩者用equals方法比较,所以添加失败,返回false boolean results=books.add(new String ("Struts")); books.add("Struts"); System.out.println(books); }}
从中可以看出,Set集合中不允许出现相同元素,我的理解是相同的值不行,变量相同也不行。
两个add方法中的变量都是new string出来的,可以说只是值相同而已,Set集合判断元素相等的方法是equals。书上说通过==运算符来算肯定是false(这是完全等于嘛),但是equals算出来就是true,所以Set里不允许任何值相同的元素。
另外我注意到一点,为什么创建集合的时候都是Setbooks=newHashSet();这种语法,包括前面的Collection也是,后面指向的是子类的对象,就为了单纯体现出多态?后来我用Setbooks=newSet();试了一下,结果发现idea自动给你把好多方法写在{}里等你完善。作为初学者我终于有点明白,你为了调用Set集合类你就要通过子类把方法的实现给讲出来啊,不然要完全实现这个Set有多麻烦,还不如现成的HashSet,这个也体现了之前书上讲的“接口体现出规范与实现的分离”好像。可能有些错误=。=
后来把Set books=new Set();后面接的方法全删了就报错了,指示一些方法没有被定义,这是最基本的了。接下来就讲到HashSet了,Set的一个典型实现类。
HashSet集合元素值可为null。当使用add方法加入元素时,HashSet有俩个方法需要判断,分别是equals()和hashCode()方法的返回值。这个书上说的我云里雾里的,先把代码敲了一遍然后去百度了下,终于弄懂。
示例代码如下,自己加了个空类d:import java.util.HashSet;//A的equals()方法总是返回true,但没有重写其hashCode()方法class A { public boolean equals(Object obj) { return true; }}//B的hashCode()方法总是返回1,但没有重写其equals()方法class B{ public int hashCode() { return 1; }}//C的hashCode()方法总是返回2,但没有重写其equals()方法class C{ public boolean equals(Object obj) { return true; } public int hashCode() { return 2; }}//dclass d{}public class TestHashSet{ public static void main(String[] args){ HashSet books=new HashSet(); //分别向books集合中添加俩个A对象,俩个B,俩个C books.add(new A()); books.add(new A()); books.add(new B()); books.add(new B()); books.add(new C()); books.add(new C()); books.add(new d()); books.add(new d()); System.out.println(books); }}
结果如下:
[B@1, B@1, C@2, A@74a14482, d@677327b6, A@4554617c, d@1540e19d]
这里刚开始我就有疑问了,明明我创建的是HashSet,怎么说的是我创建HashSet元素对象时可以重写HashSet的equals和hashCode方法呢,元素不是还可以是非引用类型吗?没方法怎么办。看半天没看懂,一百度清楚了些。
原来HashSet集合的元素对象所实现的类必须要有equals与hashCode方法而已,并不是集合本身的这俩个方法。而且HashSet在存储元素的时候,可以先判断两个对象的hashCode()返回值是否一样的,如果一样再比较equals方法的返回值。只要相同类的对象是new出来的,然后调用HashSet的add()方法,就注定了hashCode()返回的值不一样,这样不管equals()方法有没有被重写都不会起作用了,因为元素都会被添加进HashSet对象。所以一般来说都要重写hashCode方法,我看网上最常见的就是将元素类的属性进行运算得到hashCode()返回值,这也是最实用的。
还有一点需要注意,重写equals的时候,一定是这样的传参:public booleanequals(Object obj){},而不能随便定义。也就是形参必须是Object。
书中还解释了为什么开发者会发明这个HashSet集合。以前学C语言时老师说过,数组元素相当于存放在一连串的内存块中,每个元素都有索引,可能前后的内存块都已经被用了,所以没办法增加长度;而HashSet中的元素hashCode()返回值hashCode决定该元素的存放位置,相当于每个HashSet元素中的索引,且这些集合中的元素不是在内存块中紧密相连的,就像“见缝插针”一样,没有集合长度这个概念的限制,所以HashSet可以自由增加长度。且当HashSet访问元素时,可以直接通过hashCode()返回的位置找到集合元素,所以HashSet的应用速度很快(原理大概理解了)。这也解释了如果equals()总是返回false,但是hashCode相同的话,一个位置可能就放了很多元素,找到元素费时间,程序运行就慢了(书上p249页hashCode方法名写错了,偷笑)。
借鉴了一下http://blog.csdn.net/dingjingchao/article/details/53150901的代码。弄懂了equals()常见的一种重写方法,黏贴一下:
import java.util.*;class Person{ private String name; private int age; Person(String name,int age) { this.name=name; this.age=age; } public int hashCode()//重写 { return name.hashCode()+age ; } public boolean equals(Object obj)//重写 Object不能换 { if(!(obj instanceof Person)) return false; Person p=(Person)obj; System.out.println(this.name+"...."+p.name); return this.name.equals(p.name)&&this.age==p.age; } public String getName() { return name; } public int getAge() { return age; }}public class HashSetDemo{ public static void main(String[] args) { HashSet hs=new HashSet(); hs.add(new Person("lisi01",30)); hs.add(new Person("lisi02",33)); hs.add(new Person("lisi03",35)); hs.add(new Person("lisi02",33)); hs.add(new Person("lisi01",30)); hs.add(new Person("lisi04",32)); hs.add(new Person("lisi03",35)); Iterator it=hs.iterator(); while(it.hasNext()) { Person p=(Person)it.next();; sop(p.getName()+" "+p.getAge()); } } public static void sop(Object obj) { System.out.println(obj); }}
这上面的代码有些网址上是一样的,想找个时间自己复盘一下。值得一提的是name属性也有hashCode方法。意义是不是直接返回索引地址呢?写了几句代码测试了一下确实是的,int型。本来说好的一天一篇,结果昨天加班就没写了,回来还玩手机到深夜。。。蛋疼,尽量坚持住!
- JAVA学习-序号2 HashSet初入门,hashCode和equals方法
- Java中HashSet要重写equals方法和hashCode方法
- hashset中hashcode和equals方法
- JAVA HashSet equals hashcode
- 【JAVA学习】hashcode()和equals()方法剖析
- Java中的hashCode和equals方法学习
- hashset重写hashcode和Equals
- Java equals 和 hashcode 方法
- java hashCode 和 equals 方法
- Java hashCode 和 equals 方法
- HashSet的hashcode()和equals()方法的分析说明
- HashSet覆写equals 和hashcode 方法进行类别比较
- hashset中equals和hashcode方法重写问题
- 关于HashCode和equals方法在HashSet中的使用
- HashSet (需要重写hashCode和equals方法)
- HashSet 介绍, equals() 和hashcode()方法介绍
- java核心技术学习笔记8---equals()方法和hashCode()方法
- java基础入门-hashcode与equals方法
- 使用pm2启动Vue项目
- 4.spring 依赖注入的三种方式
- VPN(一):Connecting to openvpn has failed
- Java随机数生产算法
- STL 关联容器 之set(无重复有序集合)
- JAVA学习-序号2 HashSet初入门,hashCode和equals方法
- eclipse中如何向开源中国(码云)上传代码
- HDU
- 开启新的篇章
- poj 2773
- linux上搭建zookeeper集群
- SSM框架的基本搭建(Spring+Struts+Mybatis)
- "扇贝杯"南邮第二届软件和信息技术专业人才大赛题解
- 算法的一些小栗子4(归并排序)