【问题标题】:Mapping Objects to Integers in Java - use Array or Map?在 Java 中将对象映射到整数 - 使用数组还是映射?
【发布时间】:2013-01-06 09:55:36
【问题描述】:

我有需要映射到整数(或原始整数)的对象。

例如

Object[] objects = new Object[X];
objects[2]=o1;
objects[34]=o2;
objects[126]=o3;
...

所以我有一个从 0 到 X 的键范围,但只需要几个(比如说 20 个)映射对。 (映射只做一次,不会改变)

使用 Map(以及哪种实现最适合)而不是大多数未使用的“大”数组会是一个更好的主意(性能和内存使用情况)吗?

所需范围实际上可能会在开发后期扩大 - 所以如果它只对非常大的 X 很重要,那对我来说仍然很有趣。 (目前 X 是 256 - 相当小)

总结一下:我想有效地将​​数字映射到 Java 中的对象。

【问题讨论】:

标签: java arrays performance map integer


【解决方案1】:

使用地图。

性能差异应该可以忽略不计。假设当您说“性能”时,您指的是查找(正如您所说的映射只完成一次并且不会改变),使用直接数组查找的性能会更好。使用数组,您的预期查找将是O(1)。如果您有一个地图并且使用整数作为键,您的查找应该是O(1) 预期情况和O(n) 最坏情况。鉴于您提到的配对数量很少(20),性能差异不会很大。

但是,Map 的内存使用会明显更好,因为 Array 将是稀疏填充的。

更新

感谢所有提供 cmets 和反馈并帮助我学习的人。 @JohnnyO 说数组查找是 O(1) 是正确的,我根据他的反馈更正了我的帖子。我一直在想 ArrayList。

【讨论】:

  • 如果他按索引存储数据,则数组查找将是 O(1)。浪费在一个大部分为空的数组的内存占用中。
  • @JohnnyO 所以 Array 和 Map 将具有相同的查找,但 Map 应该是首选,因为内存使用?哪个地图最能处理整数?哈希映射?
  • @JohnnyO 我同意为稀疏阵列浪费内存占用。
  • @JohnnyO 你在数组查找性能上是正确的,谢谢。
  • @PhilipTenn 你应该删除“使用地图性能会更好”
【解决方案2】:

您是否使用最快的可能性(数组)或HashMap 取决于您的应用程序。您每秒有数百万次计算(数组访问)吗?是的,然后取数组,并花费 1k 的内存。
或者拿地图。
但是如果 x 很大,还有第三种解决方案: 此解决方案几乎与地图一样快(也许更快),但使用的空间更少:
使用排序的 int 数组作为对象数组的索引:

int[] idx ={2, 34, 126}
Object[] objs = {o1, o2, o3};

Idx 必须按升序排序。 现在获取键 34 的对象:

int pos= Arrays.binsearch(34, idx); // params might be wrong, please correct
Object o = objs[pos];

但是我只会将它用于大量具有最小存储空间要求的对象,其中对象在运行时不会更改。

【讨论】:

  • 这就是 android 中的稀疏数组所做的......我将进一步看看那个 2mrw
  • 你可以自己做,使用arraylist动态建立最初的索引,然后排序,创建固定的idx[]数组。准备好了。
【解决方案3】:

我会使用Map,因为这确实是它的用途。除此之外,使用Map 可能会使您的代码在未来更容易更新和管理。至于您应该使用哪种实现,在我看来 HashMap 就足够了,但如果您想按顺序保留整数键,您可能还需要考虑 TreeMap

【讨论】:

    【解决方案4】:

    数组显然会给你最快的访问,但如果你有这样的差距,你会浪费相当多的空间。

    如果您正在寻找一种灵活的数据结构,它将键(例如整数)与值相关联,其中范围内可能存在间隙,并且您以后可能会增加它,我想不出什么比地图更合适。如果您确切知道计划插入多少元素,您可能需要研究 HashMap 等实现的构造函数参数,它可以让您将底层存储的大小调整为更少的空间和更少的冲突。

    Map 的另一个结果是,如果您需要使用它执行其他面向集合的任务,您将获得更丰富的 API。

    【讨论】:

      【解决方案5】:

      正如您所说,地图是实现这一目标的好方法。我通常使用哈希映射,因为它非常快。虽然不如数组快。如果每个值只有一个键,您甚至可能想要使用 HashSet,因为它可以确保每个键只使用一个值。

      android API 有一个叫做 SparseIntArray 的东西,它应该有更好的性能,但我在标准的 java API 中没有看到它。

      如果性能真的很重要,您可能会发现 trove 库有一个合适的稀疏数组或映射。只有当您使用原语时它才会更快(在您的情况下)

      【讨论】:

        【解决方案6】:

        你真正想要的是一个 SparseArray。它是法线贴图和数组之间的折衷。

        如果您正在为 Android 开发,可以使用一个(请参见下面的链接)。否则,您可能会找到可用的实现。

        http://developer.android.com/reference/android/util/SparseArray.html

        【讨论】:

        • 有人找到了一个好的实现吗? (我不是为安卓开发)
        • Android 版本的源代码是 Apache 许可的,很容易找到(谷歌:SparseArray 源代码),它可以很容易地适应您的需求
        【解决方案7】:

        我推荐一张地图的原因有一个:可变长度。跟踪您需要映射的对象可能会变得相当乏味。使用HashMap 或类似的实现将保证您的映射对象始终有足够的容量。除此之外,使用 Map 更有意义,因为这是设计的目的,使您的代码对其他人更具可读性。我想原始数组会占用更少的内存,但实际上地图的开销对于您所说的比例来说并不是很重要。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-04-18
          • 2022-11-24
          • 2018-11-08
          • 2011-11-20
          • 2020-11-09
          • 2016-05-31
          相关资源
          最近更新 更多