java - 将大量键映射到少量值

标签 java algorithm hashmap

如果您有 1,000,000 个键(整数)映射到 10,000 个值(整数)。什么是最有效的实现方式(查找性能和内存使用)。

假设值是随机的。即不存在映射到单个值的一系列键。

我能想到的最简单的方法是 HashMap,但想知道是否可以通过对匹配单个值的键进行分组来做得更好。

Map<Integer,Integer> largeMap = Maps.newHashMap();
largeMap.put(1,4);
largeMap.put(2,232);
...
largeMap.put(1000000, 4);

最佳答案

如果已知键集在给定范围内(如示例中所示的 1-1000000),那么最简单的方法是使用数组。问题是您需要按键查找值,这将您限制为映射或数组。

下面使用值到值的映射只是为了避免等值对象的重复实例(可能有更好的方法来做到这一点,但我想不出任何方法)。该数组仅用于按索引查找值:

private static void addToArray(Integer[] array, int key, 
        Integer value, Map<Integer, Integer> map) {

    array[key] = map.putIfAbsent(value, value);
}

然后可以使用以下方式添加值:

Map<Integer, Integer> keys = new HashMap<>();
Integer[] largeArray = new Integer[1000001];

addToArray(largeArray, 1, 4, keys);
addToArray(largeArray, 2, 232, keys);
...
addToArray(largeArray, 1000000, 4, keys);

如果 new Integer[1000001] 看起来像是 hack,您仍然可以维护一种“索引偏移量”来指示与索引 0 相关联的实际 key 数组。


我会把它放在类里面:

class LargeMap {

    private Map<Integer, Integer> keys = new HashMap<>();
    private Integer[] keyArray;

    public LargeMap(int size) {
        this.keyArray = new Integer[size];
    }

    public void put(int key, Integer value) {
        this.keyArray[key] = this.keys.putIfAbsent(value, value);
    }

    public Integer get(int key) {
        return this.keyArray[key];
    }
}

和:

public static void main(String[] args) {
    LargeMap myMap = new LargeMap(1000_000);

    myMap.put(1, 4);
    myMap.put(2, 232);
    myMap.put(1000_000, 4);
}

关于java - 将大量键映射到少量值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54506530/

相关文章:

为集合 A 中的所有点查找集合 B 中最近邻居的算法

algorithm - 使用图遍历来测试图是否是完美二叉树

java - 在多个独立的 hashMap 对象中搜索特定键

java - 对 Hashmap<String, Object> 内的对象值进行排序

java - 如何使用 Streams 在 Java 8 中将 HashMap 转换为 K/V 字符串

java - 使用 Stanford CoreNLP 解析模型的问题

java - 无法使用 RSA 公钥(使用 bouncycaSTLe 创建的 PEM 文件)来加密文件

Java新时API在运行时编译和中断

java - 如何在 JSF 中正确呈现数据库中存储的类别列表

c - 以最有效的方式逐行阅读*平台特定*