Hello Java People,
我正在学习Java HashMaps。虽然我喜欢将它们放在一起是多么容易,但我正在考虑以有效的方式从地图中取出第i个条目。解释......
我们说这是我的代码:
package HashPackage;
import java.util.HashMap;
public class newHashObject {
// Nested class
public class newObject {
int Data1;
int Data2;
public newObject(int a, int b){
this.Data1 = a;
this.Data2 = b;
}
}
// HashMap to contain newObjects
HashMap<Integer, newObject> cache = new HashMap<Integer, newObject>();
// Constructor
public newHashObject(){
// populate cache with 1000 newObjects:
for(int i=0; i<1000; i++)
cache.put(i, new newObject(i, i*2+101));
System.out.println("New cache created, total objects in cache: "+cache.size());
}
}
好的,到目前为止没有任何激进。在现实生活中,我的HashMap中的条目不会被归类为等于0,1,2,3等的密钥,但是将使用基本上随机的数字密钥进行归档。也就是说,如果你要检查我的“真实”HashMap,你会看到带有键19,79,235,577,1023,1092等的条目。
现在假设我需要从HashMap中精确地提取第i个元素。我不会事先知道关键价值。例如,使用上面的“真实”地图:如果我们开始使用0对地图的条目进行编号,并且我想拉出i =第4个条目,那么我应该使用密钥1023获取条目。
我已经考虑过了,我想我可以通过我的HashMap从0迭代到i:
import java.util.Iterator;
...
// Is there a better way to do this?
public newObject iterateByIndex(int index){
Iterator<Integer> keySetIterator = cache.keySet().iterator();
int count=0;
if(index<cache.size()){
while(keySetIterator.hasNext()){
Integer key = keySetIterator.next();
if(count==index){
// We've found the ith entry in the cache
return cache.get(key);
}
count++;
}
}
return null;
}
这段代码有效,但看起来很笨重,而且效率绝对低效。我需要数百万次调用这个方法(没有谎言!),每次从0到i迭代将是一个很大的时间流失。
那么......有什么建议吗?这里的HashMap是错误的数据结构吗? (我正在使用HashMap,因为我的数据集非常非常大。)我很好奇在这种情况下,经验丰富的程序员可能会做些什么。
感谢您的任何建议, -P
答案 0 :(得分:3)
HashMap
不保留插入顺序。
如果您始终希望根据索引值或其插入顺序检索数据,那么我建议使用List
实施,如ArrayList
保证插入的顺序。
您可以围绕主数据对象创建一个包装器对象并将它们放在ArrayList
中,当您需要读取它时,可以使用您想要读取的索引值使用get
方法
答案 1 :(得分:2)
HashMap
不打算以这种方式使用,因为不保证条目的顺序。如果您确实需要key-&gt;值结构,则最好使用ArrayList
或LinkedHashMap
。
答案 2 :(得分:2)
没有有效方法从HashMap
中提取第i个条目。实际上,来自HashMap
的第i个条目甚至不是一个明确定义的概念,因为HashMap
中条目的排序未指定。
(相比之下,LinkedHashMap
的条目可以按照插入条目的顺序进行迭代。但即使对于LinkedHashMap
,也无法对#34;索引&#34;除了从开始迭代之外的条目,这是O(I)
操作,其中I
是您尝试检索的元素的索引。)
底线:如果您希望使用索引进行有效(即O(1)
)查找,则应使用ArrayList
或基本数组。
(或者,也许,使用索引值作为哈希表的键,或者使用主哈希表中条目的单独哈希表。但是,你要谈的是更复杂的数据结构和/或不同的模型&#34;索引&#34;。)
答案 3 :(得分:1)
如果你不知道密钥,那么HashMap就没用了! 改为使用ArrayList或类似的东西。
如果您的HashMap确实非常非常大(即它不适合您的可用内存),那么您可以考虑使用以下内容: http://www.oracle.com/technetwork/database/berkeleydb/overview/index-093405.html
答案 4 :(得分:1)
作为名称,&#34; 哈希地图,&#34;暗示,底层数据结构是一个&#34;哈希表。&#34;从概念上讲,它是一系列&#34;桶,&#34;关键是&#34;哈希&#34;确定要查看哪个(一个)存储桶以尝试查找该密钥。这是一个非常有效的数据结构,用于按值查找键,但它没有&#34; order的概念。&#34;
Java拥有非常丰富的数据结构选择:各种树,集合等等。即便是好的&#39; 数组!您需要选择更适合您需求的其他结构。
(并且请记住,某些东西可能是&#34;在......中......也就是说,&#34;&#34; ......一次只有一个这样的容器,与SQL表可能具有多个索引的方式大致相同。)