集合框架Set(HashSet哈希表存储、重复元素存储底层探究)
1、HashSet哈希表存储
元素是无序(存入和取出的顺序不一定一致),元素不可以重复;
查看Api会发现,set集合的功能与Collection集合的功能是一致的(就方法调用而言)
HashSet是如何保证元素唯一性的呢?
是通过元素的两个方法:hashCode与equals方法来完成;如果hashCode值相同,才会判断equals是否为true;如果hashCode值不同,那么不会调用equals。
注意:对于判断元素是否存在,以及删除等操作,依赖的方法同样是hashCode、equals方法。
List与Set判断重复对象的区别?
List只依赖于equals方法,Set依赖于hashCode、equals方法。
2、重复元素存储底层探究
HashSet为什么可以去除重复,它依靠的是什么?
add会调用俩个方法:equals和hashCode
HashSet哈希表的存储结构
返回值代表着容器中的具体位置的坐标
ps:为什么hashset自带判断字符串重复的吗?
因为 它底层调用了HashMap 利用了hashmap的键值对来判断
集合框架TreeSet(自然排序、数据结构二叉树、比较器排序)
1、自然排序
TreeSet自然排序:TreeSet可以对set集合中元素进行排序
String实现了Comparable接口,所以可以直接进行排序,引用数据类型想要排序,必须实现Comparable接口。
其他引用数据类型没有实现Comparable接口,那么会出现java.lang.ClassCastException: com.javaxl.Peroon cannot be cast to java.lang.Comparable,实现引用数据类型实现此接口就没问题了。
案例:给已知的集合进行排序
注意:排序时,当主要条件相同时,一定要判断次要条件
当给对象赋予自然排序规则的时候必须按照一下规则来先判断主要条件,再判断次要条件
2、比较器排序(比较器comparable接口,作用:使得容器具有比较性)
比如:前面的排序规则只适用于近一周的福利模块(先按年龄,再按姓氏)
系统中有另一个模块,需要对用户表中的排序规则进行更改(先按姓氏,再按年龄)
TreeSet排序的第二种方式:当元素自身不具备比较性时,或者具备的比较性不是所需要的;
注意:这时需要让集合自身具备比较性。
在集合初始化时,就有了比较方式;定义一个类,实现comparator接口,实现compare方法
当两种排序都存在时,比较器排序优先级更高,因此比较器用的多一些,在实际开发中,很多时候,引用数据类型是否具有比较性,或者比较规则,可能不由开发人员自己决定,那么开发人员想要对应的引用数据类型按照自己的排序方式进行排列,那么就需要实现comparator接口,实现compare方法 。
ps:用两个案例说明
1、打破原有的person排序规则进行排序
2、按照字符串长度进行排序(String默认是按照hashCode值进行排序的)
3、数据结构二叉树
可以对set集合进行排序,底层数据结构是二叉树;保证元素唯一性的依据是,compareTo方法return 0
注意:TreeSet排序的第一种方式,让元素自身具有比较性;
元素需要实现Comparable接口,覆盖compareTo方法;
这种方式也被称为元素的自然顺序,或者叫做默认顺序。
ps:图解二叉树排序(从左向上数排序)
那么如何让TreeSet集合中的元素怎么存进去怎么取出来呢?
compareTo方法返回值为正数,返回值写死,那么就是怎么存进去怎么取出来。
compareTo方法返回值为负数数,返回值写死,那么就是先进后出。