他山之石可以攻玉Python

Set、HashSet和TreeSet集合

2019-04-22  本文已影响30人  Djbfifjd

一、Set

  1. 不重复:内部通过equals方法来判断元素是否相等。
  2. 无序性:指的是元素的添加顺序和迭代出来的顺序不一定相等。

二、HashSet

特点是元素唯一,无序。

什么是HashSet?操作过程是怎么样的?
  1. HashSet底层实际上是一个HashMap,HashMap底层采用了哈希表数据结构
  2. 哈希表又叫做散列表,哈希表底层是一个数组,这个数组中每一个元素是一个单向链表,每个单向链表都有一个独一无二的hash值,代表数组的下标。在某个单向链表中的每一个节点上的hash值是相同的。hash值实际上是key调用hashCode方法,再通过"hash function"转换成的值
  3. 如何向哈希表中添加元素?
    先调用被存储的key的hashCode方法,经过某个算法得出hash值,如果在这个哈希表中不存在这个hash值,则直接加入元素。如果该hash值已经存在,继续 调用Key之间的equals方法,如果equals方法返回false,则将该元素添加。如果equals方法返回true,则放弃添加该元素。
  HashMap和HashSet初始化容量是16,默认加载因子是0.75。

HashSet完全继承了Set或者Collection里的方法实现 add、addAll、clear、isEmpty、size、contains、iteretor、remove等。HashSet是对HashMap的一层封装,HashMap它可以看成是一个一维数组,而一维数组里的元素又是一个单链表,类似下图所示:


HashSet图解.png

HashMap是如何保证元素唯一的呢?
根据元素的hash值以及调用equals()方法实现的。HashMap在添加元素时,首先会先计算元素的hash值,得到的结果作为一维数组的索引。然后会去调用equals()方法,来比较元素的值是否相同,如果相同,则表示同一个对象,不再添加进去,这样就保证了HashMap的唯一性,对HashSet的函数调用都会转换成合适的HashMap方法,不再赘述HashSet了。
注:这里计算处理的hash值只是类似于数组的索引,不一定就是数组的索引,这样只是便于理解。在new HashMap的时候,建议指定大小,因为如果使用默认的大小,当元素填满时,会自动扩容,这时会重新计算hash值,占用大量资源,影响效率。

三、TreeSet

TreeSet是一种树形结构,是一种红黑树,这是一种近似平衡的二叉树。TreeSet除了具有HashSet的唯一性之外,它还具有有序性。同样,TreeSet是对TreeMap的一层封装,所以,在这里介绍一下TreeMap的原理。
TreeMap保证元素唯一的特点与HashMap相似,这里不再赘述。简单介绍一下如何做到有序的。TreeMap是一个红黑树,在添加元素时,有可能会破坏树的平衡,这时会自动的做相应的旋转,来保持树的平衡。就类似于天平那样,要保证这棵树平衡。保证平衡的规则就是:父节点的值要比左子树的值大,比右子树的值小。如果添加进来的一个元素破坏了这种平衡,就会自动做相应的调整,从而保证元素的有序性。对TreeSet的函数调用都会转换成合适的TreeMap方法,所以这里也不再赘述TreeSet了。
注: TreeSet在添加元素时,元素必须有可比较性。由于基本类型的包装类以及String类已经重写了hashCode()和equals()方法,所以可以直接添加,如果添加的是自定义实体类的话,必须要实现Comparable接口,或者自定义一个比较器,实现Comparator接口,才能添加进去。
TreeSet对Set接口功能做了极大扩展,并且具有排序功能。新增了很多方法:

上一篇下一篇

猜你喜欢

热点阅读