Collection的子接口之Set接口
Set包含
- HashSet:作为Set接口的实现类;线程不安全;可以存储null值
- LinkedHashSet:作为HashSet的子类;遍历内部数据时,可以按照添加的顺序遍历
- TreeSet:可以按照添加对象的指定属性,进行排序
Set接口的特点
- 无序性:不等于随机性。存储的数据在底称数组中并非按照数组的索引顺序添加,而是根据数据的哈希值决定的。
- 不可重复性:保证添加的元素按照equals()判断时,不能返回true。即:相同的元素只能添加一个。
HashSet添加元素过程
- 当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法
来得到该对象的 hashCode 值,然后根据 hashCode 值,通过某种散列函数决定该对象
在 HashSet 底层数组中的存储位置。 - 如果两个元素的hashCode()值不相等,则直接添加值
- 如果两个元素的hashCode()值相等,会再继续调用equals方法,如果equals方法结果
为true,添加失败;如果为false,那么会保存该元素,但是该数组的位置已经有元素了,
那么会通过链表的方式继续链接。 - 如果两个元素的 equals() 方法返回 true,但它们的 hashCode() 返回值不相
等,hashSet 将会把它们存储在不同的位置,但依然可以添加成功。
注意:
在Java7中:当两个数a,b的hashCode()值相同时,但内容不同时,新元素放到数组中,指向原来放在数组中的元素,并且原来的元素不在原来的位置。即新元素不断往数组中放,旧元素跳出数组。
在Java8中:当两个数a,b的hashCode()值相同时,但内容不同时,新元素放在下面,由在数组中原来的元素指向新元素。
总结:七上八下
要求:
- 向Set中添加的数据,其所在的类一定要重写hashcode()和equals()
- 重写的hashcode()和equals()尽可能保持一致性:相等的对象必须具有相等的散列码
LinkedHashSet的使用
- LinkedHashSet 是 HashSet 的子类
- LinkedHashSet 根据元素的 hashCode 值来决定元素的存储位置,
但它同时使用双向链表维护元素的次序,这使得元素看起来是以插入
顺序保存的。 - LinkedHashSet插入性能略低于 HashSet,但在迭代访问 Set 里的全
部元素时有很好的性能,更适合遍历操作。
TreeSet的使用
- 向TreeSet中添加的数据,要求的时相同的类
- 两种排序方式:自然排序(实现Comparable接口)和定制排序(Comparator)
- 自然排序中,比较2个对象是否相同的标准:compareTo返回0,不再是equals
- 定制排序中,比较2个对象是否相同的标准:compare返回0,不再是equals
浙公网安备 33010602011771号