哈希linkedHashSet的java意义

哈希linkedHashSet的java意义,java,collections,hash,Java,Collections,Hash,我知道关于linkedHashSet的以下事情 它保持插入顺序 使用LinkedList保留顺序 我的问题是散列是如何出现的 我知道如果使用哈希,那么bucketing的概念就出现了 然而,通过检查JDK中的代码,似乎LinkedHashSet实现只包含构造函数而没有实现,所以我猜所有逻辑都发生在HashSet中 那么hashSet默认使用LinkedList 让我这样问吧。。。如果目标是编写一个集合 保持独特的价值观 使用链接列表保留插入顺序,然后。。。它可以很容易地做到没有散列。。。

我知道关于linkedHashSet的以下事情

  • 它保持插入顺序
  • 使用LinkedList保留顺序
  • 我的问题是散列是如何出现的
我知道如果使用哈希,那么bucketing的概念就出现了

然而,通过检查JDK中的代码,似乎LinkedHashSet实现只包含构造函数而没有实现,所以我猜所有逻辑都发生在HashSet中

  • 那么hashSet默认使用LinkedList
让我这样问吧。。。如果目标是编写一个集合

  • 保持独特的价值观
  • 使用链接列表保留插入顺序,然后。。。它可以很容易地做到没有散列。。。也许我们可以称这个集合为LinkedSet
  • 看到了一个类似的问题,但不是很有帮助


    如果我需要进一步解释我的问题,请告诉我。
    LinkedHashSet
    的实现实际上都在
    LinkedHashMap
    中。(而
    HashSet
    的实现实际上都是在
    HashMap
    .Le gasp中实现的!)

    HashSet
    根本没有链表


    完全可以编写一个由链表支持的
    LinkedSet
    集合,以保持元素的唯一性——只是它的性能会非常糟糕。

    这是一个“有趣”的实现。LinkedHashSet的构造函数遵从
    HashSet
    中的包私有构造函数,后者设置数据结构(LinkedHashMap)以维护迭代顺序

    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);
    }
    
    HashSet(int-initialCapacity、float-loadFactor、boolean-dummy){
    map=新LinkedHashMap(初始容量、负载系数);
    }
    

    API设计人员可以简单地公开这个构造函数,并提供适当的文档,但我想他们希望代码更“自我文档化”。

    如果仔细观察,您会发现它实际上在哈希集上使用了一些受保护的构造函数,这些构造函数只是为了它而存在,而不是常规的构造函数。e、 g

    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);
    }
    
    HashSet(int-initialCapacity、float-loadFactor、boolean-dummy){
    map=新LinkedHashMap(初始容量、负载系数);
    }
    
    因此,用于支持LinkedHashSet的密钥集实际上来自LinkedHashMap的实现,而不是像常规HashSet那样的常规HashMap。它实际上没有使用java.util.LinkedList。它只维护在bucket内容的实现中形成列表的指针(
    Map.Entry

    316私有静态类条目扩展了HashMap.Entry{
    317//这些字段包括用于迭代的双链表。
    318录入前、录入后;
    319
    320项(int散列,K键,V值,HashMap.Entry下一步){
    321 super(散列、键、值、下一个);
    322        }
    

    哈希之所以出现,是因为它是创建强制唯一性并为大多数操作提供恒定时间性能的集合的一种简单方法。当然,我们可以只使用链表并添加唯一性检查,但多个操作的时间将变为O(N)因为您必须重复整个列表以检查重复项。

    了解您问题的具体答案

    • 散列是如何出现在图片中的?(在LinkedHashSet中)
    Java文档所说的

    • 与HashSet类似,它为基本操作(add、contains和remove)提供了恒定的时间性能,假设hash函数在bucket之间正确地分散元素
    • 此链表定义了迭代顺序,即元素插入到集合中的顺序(插入顺序)
    哈希代码访问的bucket用于加速随机访问,LinkedList实现用于返回迭代器,迭代器按插入顺序吐出元素

    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);
    }
    

    希望我已经回答了您的问题?

    代码示例

    Set<Registeration> registerationSet = new LinkedHashSet<>();
    registerationSet.add(new Registeration());
    
    Set registerationSet=new LinkedHashSet();
    添加(新注册表());
    
    第2行的解释。
  • 计算注册对象的哈希代码
  • 在registerationSet中搜索hashCode以定位bucket
  • 检查入围的bucket中是否存在相等的对象
    • 3.1.如果发现相等,则将其替换为新的参考对象
    • 3.2.如果未找到,则在bucket中追加/添加注册对象的引用
  • 与之平行, 列表维护插入的所有元素的输入顺序/队列

  • 始终在末尾添加新引用
  • 如果需要更换(上述第3.1条),请删除以前发生的情况

  • 我观察到一些不同的实现方式:@JanDvorak:Trace追溯到
    HashSet
    只是作为
    Map
    的包装实现的,而
    LinkedHashSet
    只是确保该映射是
    LinkedHashMap
    。实现实际上在LinkedHashMap和HashMap中,HashSet本身就是包装ping HashMap.keySet()大多数情况下。@JanDvorak:
    LinkedHashSet
    是一个薄包装,是的,但更重要的是,
    HashSet
    也是一个围绕
    Map
    的薄包装@JanDvorak:你为什么这么说呢?
    public
    HashSet构造函数都会初始化
    HashSet
    ,以一个非链接的
    HashMap
    作为后盾然后,
    LinkedHashSet
    只调用一个特殊的包私有构造函数,该构造函数使用
    LinkedHashMap
    。为什么要将其公开?这些是可能不应该公开的实现细节。@LouisWasserman为什么不将其链接功能作为合同的一部分?@JanDvorak:linking capabilities是
    LinkedHashSet
    合同的一部分,而不是
    HashSet
    。为什么要把两者混在一起?当然,把它们混在一起对实现来说很方便,但这与