【发布时间】:2013-01-28 18:26:40
【问题描述】:
我正在执行一项任务,我必须实现自己的 HashMap。在赋值文本中,它被描述为一个列表数组,无论何时你想添加一个元素,它在数组中的最终位置是由它的 hashCode 决定的。在我的情况下,它是电子表格中的位置,所以我刚刚取了 columnNumber + rowNumber,然后将其转换为 String,然后转换为 int,作为 hashCode,然后我将它插入到数组中的那个位置。当然是以Node(key, value)的形式插入的,其中key是cell的位置,value是cell的值。
但是我必须说我不明白为什么我们需要一个列表数组,因为如果我们最终得到一个包含多个元素的列表,它不会大大增加查找时间吗?那么它不应该是一个节点数组吗?
我还发现了这个用 Java 实现的 HashMap:
public class HashEntry {
private int key;
private int value;
HashEntry(int key, int value) {
this.key = key;
this.value = value;
}
public int getKey() {
return key;
}
public int getValue() {
return value;
}
}
public class HashMap {
private final static int TABLE_SIZE = 128;
HashEntry[] table;
HashMap() {
table = new HashEntry[TABLE_SIZE];
for (int i = 0; i < TABLE_SIZE; i++)
table[i] = null;
}
public int get(int key) {
int hash = (key % TABLE_SIZE);
while (table[hash] != null && table[hash].getKey() != key)
hash = (hash + 1) % TABLE_SIZE;
if (table[hash] == null)
return -1;
else
return table[hash].getValue();
}
public void put(int key, int value) {
int hash = (key % TABLE_SIZE);
while (table[hash] != null && table[hash].getKey() != key)
hash = (hash + 1) % TABLE_SIZE;
table[hash] = new HashEntry(key, value);
}
}
那么 put 方法是否正确,首先查看 table[hash],如果它不为空并且如果那里的内容没有得到密钥,则在 put 方法中输入,然后继续到表 [(hash + 1) % TABLE_SIZE]。但如果它是同一个键,它只会覆盖该值。那这样理解正确吗?是不是因为 get 和 put 方法使用相同的方法在 Array 中查找位置,给定相同的键,它们最终会在 Array 中的相同位置结束?
我知道这些问题可能有点基本,但我花了相当长的时间试图解决这个问题,为什么任何帮助都将不胜感激!
编辑
所以现在我尝试通过 Node 类自己实现 HashMap,它只是 用一个键和一个对应的值构造一个节点,它还有一个 getHashCode 方法,在这里我只是将两个值连接起来。
我还构建了一个 SinglyLinkedList(之前分配的一部分),我将其用作存储桶。
而我的哈希函数就是 hashCode % hashMap.length。
这是我自己的实现,你觉得呢?
package spreadsheet;
public class HashTableMap {
private SinglyLinkedListMap[] hashArray;
private int size;
public HashTableMap() {
hashArray = new SinglyLinkedListMap[64];
size = 0;
}
public void insert(final Position key, final Expression value) {
Node node = new Node(key, value);
int hashNumber = node.getHashCode() % hashArray.length;
SinglyLinkedListMap bucket = new SinglyLinkedListMap();
bucket.insert(key, value);
if(hashArray[hashNumber] == null) {
hashArray[hashNumber] = bucket;
size++;
}
if(hashArray[hashNumber] != null) {
SinglyLinkedListMap bucket2 = hashArray[hashNumber];
bucket2.insert(key, value);
hashArray[hashNumber] = bucket2;
size++;
}
if (hashArray.length == size) {
SinglyLinkedListMap[] newhashArray = new SinglyLinkedListMap[size * 2];
for (int i = 0; i < size; i++) {
newhashArray[i] = hashArray[i];
}
hashArray = newhashArray;
}
}
public Expression lookUp(final Position key) {
Node node = new Node(key, null);
int hashNumber = node.getHashCode() % hashArray.length;
SinglyLinkedListMap foundBucket = hashArray[hashNumber];
return foundBucket.lookUp(key);
}
}
查找时间应该在 O(1) 左右,所以我想知道是不是这样?如果没有,在这方面我该如何改进?
【问题讨论】:
-
碰撞/性能问题在*文章中得到解决。
-
他们谈论哈希冲突,但他也有密钥冲突,如果不更改密钥编码,这将无法工作。
-
谁给了我负面评价,为什么?