我必须在地图中存储大量数据,总大小至关重要。地图数量很大,每个地图的大小都很小(大多数地图都是<10),地图在创建后不会改变。
我看到两种方式(让我们假设我知道 n 映射将被存储):
HashMap
的初始尺寸 n 并加载因子1 ArrayList
大小 n ,存储(键,值)对。与Map get()
方法
醇>
有没有更好的方法(也许是番石榴ImmutableMap
)?
答案 0 :(得分:1)
对于不再添加键的地图,可以使用优化的散列函数:尽可能小的数组,以及影响最小的碰撞。
除了学术论文之外,可以从n个不同的较小函数/值实体构建散列函数,并且可以通过尝试组合数据集来找到最优。并且具有不同的阵列大小。
由于此区域过于宽泛(如重新拍摄),请进一步搜索,或自行完成。
如果你有很多值,那么采用相同的对象实例而不是让许多不同的对象相等。这是使用身份映射Map<T, T>
仅使用第一个put键完成的。
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可能是个好主意。