【问题标题】:Using ArrayList or HashMap使用 ArrayList 或 HashMap
【发布时间】:2011-01-01 14:43:39
【问题描述】:

您好,我有一个关于是使用ArrayList 还是HashMap 的问题。

我正在尝试构建一个 Paint 程序。 每个绘制的对象都将被分配一个唯一的对象ID

如果我想在单击对象时快速检索,我应该使用arraylist 还是hashmap

一般来说hashmap的检索速度是O(1),而arraylist的检索速度是O(n)。

但是,我认为对于我的情况,因为当我单击一个对象时,我会得到 ID,因此得到数组的索引,我可以执行类似 ArraylistObject.get(ithElement); 之类的操作。 ,那么在这种情况下,这也是一个 O(1) 的检索过程?

任何输入?

谢谢!

【问题讨论】:

  • 你的ID和你的数组索引一样吗?

标签: arraylist hashmap


【解决方案1】:

如果您可以保证 ID 在一个相对较小的数值范围内,那么您应该使用普通数组(大小预初始化为最大 ID),而不是 ArrayList .这样可以确保您不会意外删除条目并移动其他所有内容以填补空白,从而导致所有内容都以错误的索引结束。普通数组也会比 ArrayList 快一点。

如果您不能做出这样的保证,请使用 HashMap。速度差异不太可能很明显,而且更容易维护。

【讨论】:

    【解决方案2】:

    从好的方面来说,您可以通过恰到好处地使用 ArrayLists 来挤出一点额外的性能。 但是删除对象将是一件非常痛苦的事情——正如 Paolo 和 Anurag 所说,您要么必须放置一个空的占位符(null ?),要么重新编号其他一些对象以填补空白。 这可能会导致性能错误和普通的旧错误。

    另一方面,HashMaps。易于使用,保证良好的性能(除非您分配的 ID 非常糟糕)。

    通过 id 检索对象可能根本不会成为应用程序的瓶颈。俗话说,过早的优化是万恶之源

    【讨论】:

      【解决方案3】:

      如果对象的 ID 可以一对一映射到数组,那么这也是 O(1) 访问,并且在实践中会比 hashmap 查找稍快(您不必计算哈希)。

      但是,问题在于删除对象时会发生什么。您将在列表中留下一个漏洞。创建新对象时,您可以继续追加到列表中,让它慢慢变得更加碎片化,或者尝试找到一个备用插槽,在这种情况下,您将进行 O(n) 搜索以寻找备用空间。

      简而言之,hashmap 可能更合适。

      【讨论】:

      • 如果它是 Java Collections 中的 ArrayList,那么即使在删除对象之后,该数组也应该是连续的(忘记实现细节)。但是,如果对象 ID 与数组索引相同,则行为会更加奇怪,因为在删除某个对象后,ID 可能会开始指向一个全新的对象,因为一切都会向上移动以填补空白。所以绝对是 HashMap。
      • 抱歉,忘记了 ArrayList 在删除元素时会重新排列底层数组(自从我使用 Java 以来已经有一段时间了),但是是的,您的观点非常有效,引用将被搞砸。跨度>
      • 使用 ID 作为索引的全部意义在于您不会删除条目,而是将它们设置为 null。
      • 所以我的观点是正确的——随着时间的推移,你会走向一个人口稀少的列表。问题是查找和重用插槽或调整数组大小和附加工作是否比仅使用哈希图更便宜?考虑到应用程序的类型(人工驱动),怀疑这不是问题,所以我仍然坚持使用哈希图,因为它是一种更直观的结构,用于保存具有唯一键的对象。
      猜你喜欢
      • 2010-10-02
      • 1970-01-01
      • 2021-11-20
      • 2014-03-30
      • 1970-01-01
      • 2016-11-04
      • 2017-08-14
      • 2011-12-20
      相关资源
      最近更新 更多