list和set底层数据结构

List和Set都继承了Collection接口

list是Java中的一个接口,它位于java.util包中,是有序的集合,元素可以重复,每个元素都有自己的索引

list集合的实现类有ArrayList,LinkedList,Vector

    ArrayList底层数据结构是动态数组(具有动态扩容的能力,当元素数量超过当前数据容量时,ArrayList会自动增加其容量),特点是查询快(数组有索引标记元素位置,查询的时候直接返回索引标记的数据即可),增 删慢(数组增加或者删除需要复制和移动数组中的数据),线程不同步

    LinkedList底层数据结构是双向链表(每个节点都包含对前一个节点后一个节点的引用),特点是增删快(只需要修改节点的前后引用即可),查询慢(链表没有对数据进行位置标记,每次获取固定位置的数据需要循环遍历链表)

    Vector底层数据结构是数组,线程同步(同步开销较高),性能不如ArrayList

set是Java中的一个接口,它位于java.util包中,是无序的集合,元素不能重复

set的实现类有HashSet,TreeSet,LinkerHashSet    

    HashSet (实际上是HashMap)底层数据结构是哈希表(数组+链表+红黑树),根据hashCode和equals方法来确定元素唯一性(基于HashCode来计算元素的存储位置,当存入的元素HashCode相同时,会调用equals方法进行确认,如果为true,则代表已经存在相同的元素)。允许存在null,但只能有一个。不保证集合的迭代顺序。线程不同步

    LinkedHashSet底层是数据结构(哈希表+双向链表)双向链表用来存储顺序,继承了HashSet,但是保证集合的迭代顺序。线程不同步

TreeSet实现了SortedSet接口,底层数据结构是红黑二叉树,实际上是TreeMap,可以确保元素处于排序状态。支持两种排序方式 自然排序和定制排序。线程不同步,不能有重复数据,不能有null数据,存储的数据类型必须是一致的。

当向treeSet添加自定义对象时,有两种排序方式:自然排序和定制排序

自然排序需要自定义对象实现Comparable接口,并重写comparaTo方法,在此方法中指明自定义的类的属性排序。

定制排序需要实现Comparator接口

都需要重写hashCode()与equals()方法

HashSet的扩容机制

底层数据结构哈希表(数组+链表+红黑树)

  1. 添加一个元素时,先得到hash值,再将hash值转化为索引,放在数组中该索引的位置
  2. 找到数组中索引位置,查看该索引是否有元素
  3. 若没有元素,则直接添加。若有元素,则调用equals方法计较。如果相同则不添加,若不同则添加在链表的尾部
  4. Jdk8中当链表中的元素个数打到8个,同时数组中的个数超过64时,就会进化成红黑树(进一步提高查询效率)。若链表中的元素达到8个,而数组中的数据未到64,则按照数组容量*2进行扩容,直到扩容到64再树化
  5. 第一次添加时,系统会扩容到,阈值为加载因子(0.75)*16 = 12
  6. 当整个数组中的元素个数打到12个 时,在添加第13个元素时,会触发数组扩容,此时阈值变为32*0.75=24,以此类推直到数组容量达到64时再树化。
Redis的有序集合(zset)和集合(set底层数据结构实现是不同的。 对于有序集合(zset),它使用了两种数据结构来实现:字典(dict)和跳跃表(skiplist)。字典用来保存元素到分数的映射关系,而跳跃表则用来进行范围操作和根据分数查询数据。由于字典是无序的,每次进行范围操作时都需要进行排序,而跳跃表虽然能执行范围操作,但查找操作的时间复杂度是O(logN)。因此,Redis使用了字典和跳跃表的组合来共同实现有序集合。 而对于集合(set),Redis使用的是字典(dict)来实现。字典是一种无序的数据结构,它可以快速地进行成员的添加、删除和查找操作,时间复杂度均为O(1)。 综上所述,Redis的zset底层数据结构实现使用了字典和跳跃表的组合,而set底层数据结构实现则只使用了字典。这样设计的目的是为了在有序集合中能够同时拥有快速的成员查找和范围操作的能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Redis第十二讲 Redis之zset底层数据结构实现](https://blog.csdn.net/huanglu0314/article/details/129967415)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [Redis中的zset底层是通过什么数据结构来实现的?](https://blog.csdn.net/qq_27198345/article/details/108674817)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值