我有HashMap
实现,但操作对我来说太慢了它必须更快,就像普通的hashmap一样。
这是代码:
package Map;
public class HashMap<K, V> {
private Entry<K, V>[] table; // Array of Entry.
private int capacity = 4; // Initial capacity of HashMap
static class Entry<K, V> {
K key;
V value;
Entry<K, V> next;
public Entry(K key, V value, Entry<K, V> next) {
this.key = key;
this.value = value;
this.next = next;
}
}
@SuppressWarnings("unchecked")
public HashMap() {
table = new Entry[capacity];
}
/**
* Method allows you put key-value pair in HashMapCustom. If the map already
* contains a mapping for the key, the old value is replaced. Note: method
* does not allows you to put null key though it allows null values.
* Implementation allows you to put custom objects as a key as well. Key
* Features: implementation provides you with following features:- >provide
* complete functionality how to override equals method. >provide complete
* functionality how to override hashCode method.
*
* @param newKey
* @param data
*/
public void put(K newKey, V data) {
if (newKey == null)
return; // does not allow to store null.
// calculate hash of key.
int hash = hash(newKey);
// create new entry.
Entry<K, V> newEntry = new Entry<K, V>(newKey, data, null);
// if table location does not contain any entry, store entry there.
if (table[hash] == null) {
table[hash] = newEntry;
} else {
Entry<K, V> previous = null;
Entry<K, V> current = table[hash];
while (current != null) { // we have reached last entry of bucket.
if (current.key.equals(newKey)) {
if (previous == null) { // node has to be insert on first of
// bucket.
newEntry.next = current.next;
table[hash] = newEntry;
return;
} else {
newEntry.next = current.next;
previous.next = newEntry;
return;
}
}
previous = current;
current = current.next;
}
previous.next = newEntry;
}
}
/**
* Method returns value corresponding to key.
*
* @param key
*/
public V get(K key) {
int hash = hash(key);
if (table[hash] == null) {
return null;
} else {
Entry<K, V> temp = table[hash];
while (temp != null) {
if (temp.key.equals(key))
return temp.value;
temp = temp.next; // return value corresponding to key.
}
return null; // returns null if key is not found.
}
}
public boolean containsKey(K key) {
int hash = hash(key);
if (table[hash] == null) {
return false;
} else {
Entry<K, V> temp = table[hash];
while (temp != null) {
if (temp.key.equals(key))
return true;
temp = temp.next; // return value corresponding to key.
}
}
return false;
}
/**
* Method removes key-value pair from HashMapCustom.
*
* @param key
*/
public boolean remove(K deleteKey) {
int hash = hash(deleteKey);
if (table[hash] == null) {
return false;
} else {
Entry<K, V> previous = null;
Entry<K, V> current = table[hash];
while (current != null) { // we have reached last entry node of
// bucket.
if (current.key.equals(deleteKey)) {
if (previous == null) { // delete first entry node.
table[hash] = table[hash].next;
return true;
} else {
previous.next = current.next;
return true;
}
}
previous = current;
current = current.next;
}
return false;
}
}
/**
* Method displays all key-value pairs present in HashMapCustom., insertion
* order is not guaranteed, for maintaining insertion order refer
* LinkedHashMapCustom.
*
* @param key
*/
public void display() {
for (int i = 0; i < capacity; i++) {
if (table[i] != null) {
Entry<K, V> entry = table[i];
while (entry != null) {
System.out.print("{" + entry.key + "=" + entry.value + "}" + " ");
entry = entry.next;
}
}
}
}
/**
* Method implements hashing functionality, which helps in finding the
* appropriate bucket location to store our data. This is very important
* method, as performance of HashMapCustom is very much dependent on this
* method's implementation.
*
* @param key
*/
private int hash(K key) {
return Math.abs(key.hashCode()) % capacity;
}
}
当我尝试输入大数据时,例如:
HashMap<Integer,String> map = new HashMap();
long startTime = System.currentTimeMillis();
for(int i = 0 ; i < 200000000; i++){
map.put(i, "kotek"+i);
}
System.out.println(System.currentTimeMillis() - startTime);
这需要太长时间。我必须在没有其他集合的情况下实现它:Set等我必须更快地放置,删除,获取和包含Key,就像普通的hashMap一样,但我不知道如何实现快速映射。
答案 0 :(得分:1)
你的地图很慢的原因是因为你有很多碰撞。你的容量是4,你永远不会扩展它。因此,put()
操作在4次put()
次调用后有效地变为大约O(N)。同样如William所述,您可以在桶的末尾添加新条目。因此,将其更改为添加为第一个元素将提高性能。但是,将地图保持为4的常量并不是一个好习惯 - 因为put()
会很好但get()
仍然是O(N)
EDIT 您不能在前面添加条目。因为您必须检查存储桶上的所有条目,以确保您没有相等的键