【问题标题】:Why doesn't SparseIntArray implement Map<Integer, Integer>?为什么 SparseIntArray 不实现 Map<Integer, Integer>?
【发布时间】:2014-02-28 05:27:23
【问题描述】:

Android 的SparseIntArray 的 API 文档打开:

SparseIntArrays 将整数映射到整数。

那么,我很好奇为什么它没有实现Map<Integer, Integer>

在我看来,所需要的只是几个不同的方法名称、一些微不足道的额外方法,以及一些禁止 null 键和值的代码......当然没有 @ 987654323@ 不能优雅地处理。我忽略了什么吗?

这并不是要抨击 Android API 的设计者。通常,当我想知道things like this 时,事实证明这是有充分理由的,我会学习一些有关该语言或平台的知识。

【问题讨论】:

  • 我认为这是因为实现 Map 接口会导致繁重的功能(装箱键,创建值和键的集合,...),而 SparseIntArray 中定义的函数是为效率。两者兼而有之会适得其反。
  • 请记住,所有这些方法在 map:developer.android.com/reference/java/util/Map.html 中都是必需的(另外,如果您将其称为更高抽象的映射,则不能使用 SparseIntArray 特定函数。并使用 @ 进行迭代987654328@ 和 keyAt 旨在比 Map 中的 entrySet 更高效,但不太方便)

标签: java android api collections


【解决方案1】:

JavaDoc for SparseIntArray 也说

SparseIntArrays 将整数映射到整数。不同于普通的数组 整数,索引中可能存在间隙。 它的目的是更多 内存效率比使用 HashMap 将 Integers 映射到 Integers, 都是因为它避免了自动装箱键和值及其数据 结构不依赖于每个映射的额外入口对象。

我们可以得出选择 SparseIntArray 而不是 Map 的以下原因:

  • 由于我们希望在原始整数之间进行映射,因此最好避免自动装箱。
  • 在 Map 中,将对象作为键/值会带来繁重的哈希计算、解决哈希冲突、链接单个存储桶中的多个条目等。这些都不是必需的,因为我们正在处理原始键/值对。请注意,SparseIntArray 带有性能警告。由于值存储在二叉搜索树数组数据结构中,插入和删除将是昂贵的操作。因此,对于少量数据,它是一个不错的选择。

顺便说一句,我会说 JavaDoc 应该说得更具体

“SparseIntArrays 将原始整数映射到整数。”

而不是说

“SparseIntArrays 将整数映射到整数。”

【讨论】:

  • 对不起;我不明白这如何回答这个问题。 AFAIK,地图接口没有定义实现在引擎盖下的工作方式,也没有定义它的效率——我相信这就是重点。
  • 我可能误解了你的问题。它更多是 SparseIntArray 的接口和设计选择。一旦有任何线索,会及时通知您。
  • 是的。问题是他们为什么做出这样的选择。
  • 如上面的文档中所述,它避免了自动装箱并直接使用原始整数(不是Integer 包装器)。见:docs.oracle.com/javase/tutorial/java/data/autoboxing.html
  • @MichaelScheper 在对 SparseIntArray 进行更多分析后编辑了我的答案。 :)
【解决方案2】:
  • 实现Map 非常繁重。您需要entrySetkeySet 之类的方法,这在SparseIntArray 中并不方便。

  • 地图键是对象,所以你需要不断装箱/拆箱。

  • SparseIntArray 提出了一种通过Map 枚举的不同方式,使用其特定的keyAtvalueAt,这非常快。

如果SparseIntArray 实现了Map&lt;Integer, Integer&gt;,你会很想写:

Map<Integer, Integer> intMap = new SparseIntArray();

但是你会被困在只有 Map 提供的枚举功能上。

【讨论】:

  • 第一点:我不同意。 entrySetkeySet 不会很难实现,会在 n 时间内运行,并且如果它们未被使用,也不会降低性能。第二点:是的,我认为这是真正的答案,但 Omkar 打败了你。 :-) 第三点:这没有回答为什么这个问题。这确实是引发这个问题的原因——非标准 API 很痛苦。
【解决方案3】:

如果它实现了Map&lt;Integer,Integer&gt;,它将不得不将Integer对象作为输入和输出值而不是原始的int值来处理,所以这个类避免装箱的全部意义将丢失。

【讨论】:

  • 是的!但是@Omkar 打败了你。 ☺ 谢谢!
猜你喜欢
  • 2013-06-09
  • 1970-01-01
  • 2022-09-30
  • 1970-01-01
  • 1970-01-01
  • 2014-05-04
  • 2019-12-06
  • 1970-01-01
  • 2014-12-19
相关资源
最近更新 更多