【问题标题】:Why would someone use Array over HashMap if the situation allows for HashMap?如果情况允许 HashMap,为什么有人会在 HashMap 上使用 Array?
【发布时间】:2018-02-01 22:20:17
【问题描述】:

我在这里阅读了一个解决方案(https://leetcode.com/problems/longest-substring-without-repeating-characters/solution/).They 说在正常情况下,当我们不知道键的(字符)范围时,我们使用 hashmap。

还有另一种解决方案,当我们对字符集有特殊要求时,我们可以使用数组来代替。

前面的实现都没有假设字符串s的字符集。

如果我们知道字符集很小,我们可以将 Map 替换为 一个整数数组作为直接访问表。

常用的表格有:

int[26] for Letters 'a' - 'z' or 'A' - 'Z'
int[128] for ASCII
int[256] for Extended ASCII

不仅在这里,而且在 Cracking the Coding 采访书中的几个位置,他们使用一个数组,其中字符是键,通过等效整数表示一个字符并将值存储在该数组中的相应位置。

当我们手头有 hashmap 时,为什么我们要与数组斗争? 有什么原因吗?

【问题讨论】:

  • 速度更快,占用空间更少。
  • 和更少的时间和空间开销
  • 他们认为它更快并且使用更少的空间。
  • @TimothyTruckle 或者他们已经测量过,发现它需要更少的时间和空间。数组T[] 逻辑上是Map<int, T>;它的开销几乎与您在 Java 中可以摆脱的一样少。
  • @AndyTurner 通常节省的空间并不重要,因为应用程序没有受到内存不足的影响,并且基于数组的解决方案的编码(和测试)时间通常超过生命周期中运行时节省的时间应用程序的数量级...但是,将 C++ 最佳实践(如本例中的手动内存管理)接管到 Java 通常不是一个好主意....

标签: java arrays hashmap key-value


【解决方案1】:

当我们手头有 hashmap 时,为什么我们还要处理数组问题

只是不要与他们斗争,他们并不难:)

我的意思是,这更难:

Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < 26; ++i) {
  map.put(i, 0);
}
// Or, if you want to use Streams:
// IntStream.range(0, 26).boxed().collect(Collectors.toMap(i -> i, i -> 0));

int[] array = new int[26];
// No need to initialize anything, Java sets elements to zero by default.

HashMap 的问题在于您必须存储键和值。特别是,Java HashMap 必须存储引用类型的密钥,因此您必须先将密钥装箱,然后再将它们放在那里。因此,您损失了两次,既是在存储密钥方面,又是不得不低效地存储它们。

数组T[] 在逻辑上是一个固定大小的Map&lt;int, T&gt;,具有密集、连续的键。您不需要存储键,因为它们隐含在元素索引的概念中。它可以非常快速地访问特定元素,无论是获取还是设置。

这是一种优化:如果您所做的只是获取/设置元素,那么您不需要所有其他 gubbins 以及完整的 Map 实现。但是使用该优化(与所有优化一样)您有缺点,例如无法轻松泛化到更大的关键空间。

【讨论】:

    猜你喜欢
    • 2023-03-16
    • 2012-12-02
    • 2013-12-30
    • 2010-09-17
    • 2014-07-20
    • 2019-11-29
    • 2016-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多