• 集合框架----源码解读LikedeHashSet篇


    1.官方介绍

    Hash表和链表实现了Set接口,具有可预测的迭代顺序。该实现与HashSet的不同之处在于它维护了一个贯穿其所有条目的双向链表。该链表定义了迭代顺序,即元素插入集合的顺序(插入顺序)。注意,如果一个元素重新插入到集合中,插入顺序不受影响。当s .包含( e )在调用之前立即返回true时调用(如果s . add ( e ) ,则元素e重新插入到集合s中)。
    这种实现使其客户端免受HashSet提供的未指定的、通常是混乱的排序,而不会增加与TreeSet相关的成本。它可以用来产生一个集合的副本,该集合与原集合具有相同的顺序,而不管原集合的实现方式如何:

      void foo(Set s) {
               Set copy = new LinkedHashSet(s);
               ...
           }
     

    这种技术特别有用,如果一个模块在输入上取一个集合,复制它,然后返回由复制的顺序决定的结果。(客户一般赞赏以相同的顺序返回的东西。)
    该类提供了所有可选的Set操作,并且允许空元素。与Hash Set一样,它为基本操作(添加、包含和移除)提供了常数时间性能,假设哈希函数在桶之间适当分散元素。性能很可能只是略低于Hash Set,因为增加了维护链表的费用,但有一个例外:在Linked Hash Set上迭代需要与集合大小成比例的时间,而不管其容量如何。在HashSet上进行迭代可能比较昂贵,需要的时间与其容量成正比。

    一个链接哈希集有两个影响其性能的参数:初始容量和负载因子。对于HashSet而言,它们是精确定义的。但需要注意的是,选择过高的初始容量值对该类的惩罚不如Hash Set严重,因为该类的迭代次数不受容量的影响。
    注意,这种实现并不同步。如果多个线程同时访问一个链接哈希集,并且至少有一个线程修改该哈希集,则必须对其进行外部同步。这通常是通过对一些自然封装集合的对象进行同步来完成的。如果不存在这样的对象,则应该使用Collections . synchronoused Set方法对集合进行"包装"。这最好在创建时完成,以防止意外的不同步访问集合:

    Set s = Collections.synchronizedSet(new LinkedHashSet(...));

    该类迭代器方法返回的迭代器是快速失败的:如果在迭代器创建后的任何时候修改了集合,除了通过迭代器自己的移除方法之外,迭代器将抛出Concurrent ModificationException异常。因此,在面对并发修改时,迭代器能够快速、干净地失效,而不是冒着在未来不确定时刻发生任意、非确定性行为的风险。
    需要注意的是,迭代器的快速失效行为是无法保证的,因为通常情况下,在存在不同步的并发修改的情况下,无法做出任何硬性保证。快速迭代器在尽力而为的基础上抛出Concurrent ModificationException。因此,编写一个依赖于该异常的程序来保证其正确性是错误的:迭代器的失效快行为应该只用于检测bug。

     2.LikedHashSet的特性

    LikedHashSet是对HashSet的升级,主要是解决HashSet存放元素无序的问题,LikedHashSet底层就是LikedHashMap

    3. 手写LikedHashSet

    1. package com.example.list.list;
    2. import java.util.LinkedHashMap;
    3. //手写LinkedHashSet
    4. public class LinkedHashSet {
    5. private LinkedHashMap linkedHashMap;
    6. private static final Object PRESENT = new Object();
    7. public LinkedHashSet() {
    8. linkedHashMap = new LinkedHashMap();
    9. }
    10. public void add(E e){
    11. linkedHashMap.put(e, PRESENT);
    12. }
    13. @Override
    14. public String toString() {
    15. return "LinkedHashSet{" +
    16. "linkedHashMap=" + linkedHashMap +
    17. '}';
    18. }
    19. }
  • 相关阅读:
    P5143 攀爬者(快速排序)
    猿创征文 | kafka框架从入门到精通(全)
    Python Faker批量生成测试数据
    Java回调函数是什么?实现的方式有哪些
    java计算机毕业设计企业公开招聘系统源码+数据库+系统+lw文档+mybatis+运行部署
    在Linux/Ubuntu/Debian上将富文本Markdown (`.md`) 文件转换为HTML
    代码随想录三刷day37
    大学里遗憾的事,希望你无怨也无悔
    国际财务系统基于ShardingSphere的数据分片和一主多从实践
    mysql使用FIND_IN_SET函数解决两张表没有主键id强关联,而是A表中的某个字段值,存在B表中的集合字段中
  • 原文地址:https://blog.csdn.net/qq_42847719/article/details/128089922