如何用地图节省空间

时间:2015-04-23 08:57:24

标签: java memory dictionary

我必须在地图中存储大量数据,总大小至关重要。地图数量很大,每个地图的大小都很小(大多数地图都是<10),地图在创建后不会改变。

我看到两种方式(让我们假设我知道 n 映射将被存储):

  1. 使用HashMap的初始尺寸 n 并加载因子1
  2. 使用ArrayList大小 n ,存储(键,值)对。与Map
  3. 一样实施get()方法

    有没有更好的方法(也许是番石榴ImmutableMap)?

3 个答案:

答案 0 :(得分:1)

请参阅Perfect hash function

对于不再添加键的地图,可以使用优化的散列函数:尽可能小的数组,以及影响最小的碰撞。

除了学术论文之外,可以从n个不同的较小函数/值实体构建散列函数,并且可以通过尝试组合数据集来找到最优。并且具有不同的阵列大小。

由于此区域过于宽泛(如重新拍摄),请进一步搜索,或自行完成。

如果你有很多值,那么采用相同的对象实例而不是让许多不同的对象相等。这是使用身份映射Map<T, T>仅使用第一个put键完成的。

  • TreeMap用于大数据,与LinkedList w.r.t一样低效。 ArrayList中。
  • HashMap的实现对于提高效率非常有意义。最后一个可以和ArrayList.trimToSize()做同样的事情,尽管可能不相关。

答案 1 :(得分:0)

有很多方法可以做到这一点,而且很难准确预测空间需求(取决于例如Java对象开销和打包,以及您所使用的架构!)。您可能需要使用实际(或代表性)数据,使用不同的方法进行内存基准测试。

一种方法是使用数组(一个用于键,一个用于值)。

另一个想法是使用单个外部Map,但组合一个键以使用每个内部值的键来寻址每个内部地图。这样,您就可以避免许多小地图的开销。

所以我们的第一张地图:

"one" -> 1
"two" -> 2

和第二张地图

"three" -> 3

我们将所有条目存储在一个Map中,例如:

"1-one" -> 1
"1-two" -> 2
"2-three" -> 3

(你可以使用一个类似的想法,使用一个大数组或ArrayList,存储值对,如果你可以以排序的方式存储对,这样你就可以使用二进制搜索有效地找到它们)。或者是一对数组/数组列表,因此您不需要将键/值包装到Pair对象中。

答案 2 :(得分:0)

如果空间是您最关心的问题,那么使用ArrayList甚至普通数组将是最佳选择。您必须测试串行查找是否会导致性能显着下降;最有可能不会。如果您的数据是Comparable,那么您可以使用二进制搜索,但我怀疑这是否真的有助于这么小的尺寸。

有一点需要关注的是,你是否有时会有更大的地图;在这种情况下添加检查并使用常规HashMap可能是个好主意。