只需使用开放式寻址编码我自己的HashMap实现,键类型为int,值类型为long。但是,即使我只是添加一个新值,它的工作也比普通的java实现慢。有什么方法可以使其更快?
public class MyHashMap {
private int maxPutedId =0;
private int size;
private int[] keys;
private long[] values;
private boolean[] change;
public MyHashMap(int size){
this.size = size;
keys = new int[size];
values = new long[size];
change = new boolean[size];
}
public MyHashMap(){
this.size = 100000;
keys = new int[size];
values = new long[size];
change = new boolean[size];
}
public boolean put(int key, long value){
int k = 0;
boolean search = true;
for(int i = 0;i<maxPutedId+2;i++){
if(search&& !change[i] && keys[i] == 0 && values [i] == 0 ){
k=i;
search = false;
}
if(change[i] && keys[i] == key ){
return false;
}
}
keys[k] = key;
values[k] = value;
change[k] = true;
maxPutedId = k;
return true;
}
public Long get(int key) {
for (int i = 0; i < size; i++) {
if (change[i] && keys[i] == key) {
return values[i];
}
}
return null;
}
public int size(){
int s = 0;
for(boolean x: change){
if(x) s++;
}
return s;
}}
答案 0 :(得分:0)
您尚未实现哈希表;没有任何哈希。例如,您的get()方法正在对键数组进行线性遍历。散列表的实现应该能够计算最有可能找到键的数组条目(实际上,如果存在键并且没有散列冲突,就可以找到它)。
一个简单的哈希表如下所示:我们首先根据密钥计算一个哈希。然后我们看一下表格中的那个插槽。理想情况下,将在其中找到密钥。但是,如果密钥不存在,则可能是由于冲突所致,因此我们扫描(假定为开放式寻址)在随后的插槽中寻找密钥-直到我们遍历整个表或找到一个空位为止。 >
我写了“ get”,因为它看起来更简单:-)
这是“我的头上”代码,因此您需要仔细检查。
Long get(int key) {
int h = hash(key);
// look in principal location for this key
if (change[h] && keys[h] == key)
return values[h];
// nope, scan table (wrapping around at the end)
// and stop when we have found the key, scanned
// the whole table, or met an empty slot
int h0 = h; // save original position
while ((h = (h+1) % size) != h0 && change[h])
if ( keys[h] == key)
return values[h];
return null;
}
我可能应该先写'put'以便更具启发性。
用于int
键的哈希函数可以计算为key % size
。那是否是一个很好的哈希值取决于密钥的分配。您想要一个避免冲突的哈希。