A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 彭盼 中级黑马   /  2012-3-25 11:03  /  6046 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

老师在讲这一节内容时,重点讲到要用复写equals和hashCode方法来避免重复元素,但我有个问题,如何对HashSet中的元素进行自定义排序呢,
可否采用TreeSet的两种排序办法即让类实现Comparable接口,覆盖compareTo方法或者用实现\comparator接口的方法呢,老师在TreeSet中
讲解的这两种排序方式是否对整个Set集合都有效呢

5 个回复

倒序浏览
HashSet是无序的。HashSet在调用add()的时候没有排序,TreeSet在调用add()的时候是排序的,它们的add()实现都是调用Map的put()方法,想要理解清楚建议看一下源码。

评分

参与人数 1技术分 +1 收起 理由
房宝彬 + 1

查看全部评分

回复 使用道具 举报
HashSet不能重复存储equals相同的数据 。原因就是equals相同,数据的散列码也就相同(hashCode必须和equals兼容)。大量相同的数据将存放在同一个散列单元所指向的链表中,造成严重的散列冲突,对查找效率是灾难性的。HashSet的存储是无序的 ,没有前后关系,他并不是线性结构的集合。hashCode必须和equals必须兼容, 这也是为了不能重复存储euals相同的数据这一点。

评分

参与人数 1技术分 +1 收起 理由
房宝彬 + 1

查看全部评分

回复 使用道具 举报
hashSet的功能主要是为了保重元素的唯一性,通过判断HashCode和equals方法,来存入数据,而TreeSet的底层结构就是二叉树,所以存入时自动就有排序的动作
所以当你的数据集合需要那种功能的时候,你就选择相应的集合形式就可以了
HashSet因为不需要排序,只需要保证唯一性,所以添加数据的效率显然高于TreeSet
回复 使用道具 举报
Set集合存入的元素是不能重复的。
HashSet集合中所存入的元素是无序的,为了保证所存入元素的唯一性,会首先调用hashCode方法获取元素的hash值,如果与集合中所存元素的hash值不一样就把元素存入集合中,如果有相同的会再调用equals方法判断是否为同一个元素。
TreeSet存入元素的实现方法和HashSet是一样的,但是TreeSet集合是有序的,如果你想自定义排序,首先是实现Comparable接口,重写compareTo方法,但是存入集合的时候还得按照这样的思想先重写hashCode方法和equals方法,只有自己所需的元素都存入集合并且存入集合的元素都是唯一的排序才是有意义的,当然还可以自定义一个构造器实现Comparator接口,重写compare方法,两种排序同时存在的话,以自定义构造器为先

评分

参与人数 1技术分 +1 收起 理由
房宝彬 + 1

查看全部评分

回复 使用道具 举报
简单点说,首先大概念Set集合,它里面的元素不能重复而且集合没有索引,HashSet底层的数据结构是哈希表,在把自定义对象存入HashSet的时候,会比较自定义对象的哈希值,根据哈希值的不同去判断对象(重写hashCode()方法),如果有2个对象的哈希值相同那么,在利用重写的equals()方法比较自定义对象是否一样,这样可以保证HashSet里的元素的唯一性。
而对于TreeSet方法,它的底层数据结构是二叉树,如果你学过数据结构会比较好理解,如果没有学过,你可以简单的这样理解:2个自定义对象比较(比较内容自定),当前元素和集合里的每一个元素比较,如果比当前比较的对象小,向左边枝叶走,如果大向右边枝叶走,最后总有一个合适它的地方,在编写程序的时候,有2中方法,一种就是你说的自定义对象实现Comparable接口重写里面的compareTo(Object obj)方法,还有一种就是写一个比较器的类,该类实现Comparator接口重写compare(object o1,Object o2)方法,但是无论你使用哪一种方法,TreeSet集合最后根据的是你返回值来判断比较大小的,正数大,0为相等,负数小。
另外你提到的共用方法和属性,你打开API文档,看一下Set接口的通用方法,和util包中我们使用到的接口,有哪些类实现了他们,这样思路就清楚了。

评分

参与人数 1技术分 +1 收起 理由
房宝彬 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马