C# hashmaps的缺点是什么?

C# hashmaps的缺点是什么?,c#,java,data-structures,C#,Java,Data Structures,无论我使用哪种语言,我的目标总是使用hashmap的等价物。然而,我正在进行一些实践面试问题,它问我这有什么限制 我能想到的唯一原因是主内存有限,但这不仅限于hashmaps,还包括ArrayLists等。还有可能发生冲突。如果冲突避免要求严格,或者如果哈希空间较小,则编写和/或执行哈希函数的成本可能会很高。为正确的作业使用正确的数据结构。如果不需要钥匙访问,请不要使用地图 就HashMap的限制而言,我想如果项目的Hash算法不好,它可能会受到影响,但仅此而已。HashMap的使用是因地制宜的

无论我使用哪种语言,我的目标总是使用hashmap的等价物。然而,我正在进行一些实践面试问题,它问我这有什么限制


我能想到的唯一原因是主内存有限,但这不仅限于hashmaps,还包括ArrayLists等。

还有可能发生冲突。如果冲突避免要求严格,或者如果哈希空间较小,则编写和/或执行哈希函数的成本可能会很高。

为正确的作业使用正确的数据结构。如果不需要钥匙访问,请不要使用
地图


就HashMap的限制而言,我想如果项目的Hash算法不好,它可能会受到影响,但仅此而已。

HashMap的使用是因地制宜的

如果你的散列键没有被很好地选择,你的散列映射将以相当于一个列表的速度运行,这会增加巨大的内存占用问题

通常,当您要对数据执行迭代任务时,哈希映射是一个错误的选择

链式哈希表也继承了链表的缺点。 存储小键和值时,下一个 每个条目记录中的指针都可能是有效的。额外的 缺点是遍历链表的缓存很差 性能,使处理器缓存无效


一个(非常重要的)限制是,您不应该将它们用于具有不稳定(可变)哈希代码的类型

这意味着HashMap中不保留元素的顺序。下一个问题是“如何解决这个问题”。答案是:使用LinkedHashMap能够以插入元素的相同顺序获取元素,并使用适当的比较器进行树形映射,以根据您想要的任何标准控制顺序

哈希表的典型替代方法是二叉树。虽然哈希表通常速度更快,但内容的顺序没有任何意义;使用二叉树对内容进行排序。

Java上的hashmap的一个缺点是它不同步。如果多个线程同时访问哈希映射,并且至少有一个线程在结构上修改了该映射,则必须在外部对其进行同步。您必须将其包装在
集合中。synchronizedMap
我可以想到两件事。一个是,在迭代hashmap时,不能保证排序(稳定或其他)。另一个原因是,当您对它们进行迭代时,它们可能会对缓存进行重击

  • 虽然哈希表具有恒定的插入时间,但哈希表偶尔需要扩展其内部结构并重新存储其条目。这是一个成本与哈希表的当前大小成比例的操作。这样做的结果是插入时间并不总是一致的,即插入将是恒定的,
    O(1)
    ,但随着表格的增长,偶尔您会注意到线性延迟,
    O(n)
    。(这种行为特征导致一些人建议在默认/幼稚的情况下更倾向于树而不是哈希表。)
  • 您需要确保所添加项的哈希算法是正确的。这意味着,对于任意一组元素,生成的哈希代码在哈希代码类型的范围内分布良好(在Java和C中,这是
    int
    )。如果有许多项具有相同的值(有人吗?),则哈希表将降级为一个复杂的链表,性能将显著降低
  • 您需要确保项目的哈希代码不会随时间变化,并且实现了相等方法(Java的
    equals()
    或.NET的
    equals()
    )来比较哈希代码使用的相同字段集。(理想情况下,这意味着您添加到表中的对象是不可变的,但您也可以改为确保任何可变字段与哈希代码计算和等于方法无关:这是一种危险的策略。更改哈希代码后,当您稍后来ret时,表将无法找到您已经添加到表中的条目。)把它们拿走
  • 哈希表通常不保留顺序——无论是自然顺序还是插入顺序(通常使用并行结构来保持顺序,或者在迭代时执行相对昂贵的排序)
  • 另见:

    映射可能是持久的 我能想到的唯一原因是主内存有限,但这不仅限于hashmaps,还包括ArrayLists等等

    地图不需要仅限于内存

    有些数据库提供了一个接口,例如Postgres中的hstore或H2数据库引擎中的hstore。第二个数据库使用Java中定义的接口,就像内存中的实现一样

    地图也可以分布在计算机网络上,保留地图的一部分。有几种这样的产品可用

    注意事项,如并发性、空值和迭代顺序 键值存储的不同实现(通常称为映射或字典)的特征各不相同。您提到了HashMap,但这只是映射的一种方法。有映射,也有映射通过引用(指针)跟踪对象在Java中,
    EnumMap
    对于基于子类的键进行了高度优化,其中项在内部表示为枚举中定义的所有位置的位图,从而产生非常快的执行速度和占用的内存非常少。某些实现可能是mor根据数据量的不同,例如Java中的
    ConcurrentSkipListMap
    ,e与其他文件相比具有高度并发性

    某些映射可能接受或禁止键和/或值中的null。这可能有助于或违反业务规则的需要

    在某些情况下,您可能需要