Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将一组大的键映射到一组小的值_Java_Algorithm_Hashmap - Fatal编程技术网

Java 将一组大的键映射到一组小的值

Java 将一组大的键映射到一组小的值,java,algorithm,hashmap,Java,Algorithm,Hashmap,如果有1000000个键(整数)映射到10000个值(整数)。最有效的实现方式(查找性能和内存使用)是什么 假设这些值是随机的。i、 e没有映射到单个值的键范围 Map<Integer,Integer> largeMap = Maps.newHashMap(); largeMap.put(1,4); largeMap.put(2,232); ... largeMap.put(1000000, 4); 我能想到的最简单的方法是HashMap,但我想知道,如果将匹配单个值的键分组,是否

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

假设这些值是随机的。i、 e没有映射到单个值的键范围

Map<Integer,Integer> largeMap = Maps.newHashMap();
largeMap.put(1,4);
largeMap.put(2,232);
...
largeMap.put(1000000, 4);
我能想到的最简单的方法是HashMap,但我想知道,如果将匹配单个值的键分组,是否可以做得更好

Map<Integer,Integer> largeMap = Maps.newHashMap();
largeMap.put(1,4);
largeMap.put(2,232);
...
largeMap.put(1000000, 4);
Map-largeMap=Maps.newHashMap();
大面积放置(1,4);
大面积放置(2232);
...
大额存托凭证(1000000,4);

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

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

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

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


HashMap是最糟糕的解决方案。整数的散列就是它本身。如果你想要一个容易获得的解决方案,我会说树形图。您可以编写自己的专用树映射,例如,将键拆分为两个短键,并在树映射中包含一个树映射。

我不确定您是否可以通过分组来优化这里的任何内容。如果您希望按值而不是按键进行查找(即获取具有特定值的所有键),则“反向”映射可能会给您带来稍好的性能,但由于您没有明确表示要这样做,因此我不会采用这种方法

对于优化,如果关键点在固定范围内,则可以使用
int
数组而不是贴图。数组查找是O(1),基本数组使用的内存比映射少

int offset = -1;
int[] values = new int[1000000];
values[1 + offset] = 4;
values[2 + offset] = 232;
// ...
values[1000000 + offset] = 4;
如果范围不是从
1开始
可以调整偏移量


还有像trove4j这样的库,它们为此类数据提供了比标准集合更好的性能和更高效的存储,虽然我不知道它们与简单数组方法相比如何。

已知的键是
1-1000000
?如果这有帮助,可以知道是的键在固定范围内。如果键===映射的值,映射映射映射为您提供了什么。@Chris我只使用它来避免多次实例化
相等的值(请参阅
map.putIfAbsent(value,value)
调用)。如答案所述,可能还有一种更好的方法,我还没有找到。我不明白。如果将
put
实现更改为
this.keyArray[key]=value;
,那么结果就是数组的包装器(在许多方面,这可能是“最好的”)不管怎样,这里的解决方案)对于
Integer
@Marco13来说,谈论“输入相等值”似乎没有意义。原因是:我想保留最多10000个可能值的实例/对象。如果调用
put(99999912345)
12345
被自动装箱到一个新的
Integer
对象中。好的…但是调用
put(9999812345)
再次将导致另一个
12345
Integer对象。这对于
Integer
可能无关紧要,但我想限制值实例的数量。换句话说,对于
12345
,无论贴图在何处将其作为值,我都拥有相同的对象。这就是
This.keys.putIfAbsent
的帮助所在g(带)
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);
}
int offset = -1;
int[] values = new int[1000000];
values[1 + offset] = 4;
values[2 + offset] = 232;
// ...
values[1000000 + offset] = 4;