如何在Java中创建自己的HashMap?
我知道散列算法,知道如何将“key”转换成一个等价的整数(使用一些数学上的随机表达式),然后将其压缩并存储到bucket中 但有人能给我指出一个应该用作基线的实现或至少是数据结构吗如何在Java中创建自己的HashMap?,java,algorithm,data-structures,hashmap,Java,Algorithm,Data Structures,Hashmap,我知道散列算法,知道如何将“key”转换成一个等价的整数(使用一些数学上的随机表达式),然后将其压缩并存储到bucket中 但有人能给我指出一个应该用作基线的实现或至少是数据结构吗 我在web上的任何地方都没有找到它。创建一个实现java.util.Map接口的类,并填写给定的方法只需使用eclipse和最新的JDK即可。Java核心包的源代码随JDK一起提供。打开HashMap类,就可以开始了。一些方法实现可能来自AbstractMap、AbstractCollection等。这是因为适当的O
我在web上的任何地方都没有找到它。创建一个实现
java.util.Map
接口的类,并填写给定的方法只需使用eclipse和最新的JDK即可。Java核心包的源代码随JDK一起提供。打开HashMap类,就可以开始了。一些方法实现可能来自AbstractMap、AbstractCollection等。这是因为适当的OO设计。您可以导航到eclipse中的所有JDK类
更新:为什么要使用Eclipe(或IDE)而不只是打开zip文件?
IDE可用于在类之间来回移动,通常有利于“读取”代码。注意:并非所有的方法实现都在一个文件(如HashMap.java)中,因此像notepad++或textpad这样的简单文本编辑器可能不够。像eclipse/IDEA这样成熟的IDE可以使它变得更容易。至少它对我有用:)如果你想要一个快速且内存高效的实现,你需要使用一个数组来支持你的地图。使用要索引到数组中的哈希算法,并将对象存储在数组的该插槽中 有很多小细节需要注意。何时调整数组大小,如何检测和解决哈希冲突等
我建议让您的类实现java.util.Map,因为它会让您很好地了解哪些方法是必要的和有用的。创建自己的HashMap 1。数据结构需要存储密钥和键值对。 创建一个Entry类来存储HashMap条目。 变量:键、值和下一个 下一个变量用于使用链接(链表)避免hashmap的冲突 2。put()方法将新条目放入hashmap。 使用哈希(哈希代码%SIZE)标识存储桶 a如果该存储桶中不存在任何元素:将其作为新条目放置 b如果元素已存在: 如果元素重复,则替换旧元素,否则查找链中的最后一个元素,并将新条目添加到最后一个元素的下一个指针 3。get()方法:返回hashmap中的元素
A.通过计算键的散列(hashcode%SIZE)来识别元素bucket,并使用equals方法返回元素。尽管这是一个非常古老的问题,但我认为我应该为初学者提供一个易于理解的答案 HashMap简单解决方案的自定义实现:
class HashMapCustom<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 HashMapCustom() {
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.
}
}
/**
* 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;
}
}
类HashMapCustom{
私有条目[]表;//条目数组。
private int capacity=4;//HashMap的初始容量
静态类条目{
K键;
V值;
进入下一步;
公共输入(K键、V值、下一个输入){
this.key=key;
这个值=值;
this.next=next;
}
}
@抑制警告(“未选中”)
公共HashMapCustom(){
表=新条目[容量];
}
/**
*方法允许您将键值对放入HashMapCustom中。
*如果映射已经包含键的映射,则替换旧值。
*注意:方法不允许您放置null键,尽管它允许null值。
*实现还允许您将自定义对象作为键。
*主要功能:实施为您提供了以下功能:-
*>提供如何覆盖equals方法的完整功能。
*>提供如何覆盖hashCode方法的完整功能。
*
*@param newKey
*@param数据
*/
公共作废put(K newKey,V data){
if(newKey==null)
return;//不允许存储null。
//计算密钥的散列。
int hash=hash(newKey);
//创建新条目。
Entry newEntry=新条目(newKey,data,null);
//若表位置不包含任何条目,那个么将条目存储在那个里。
if(表[hash]==null){
表[hash]=newEntry;
}否则{
前一项=空;
当前条目=表[哈希];
而(当前!=null){//我们已经到达了bucket的最后一个条目。
if(当前键等于(新键)){
if(previous==null){//必须在bucket的第一个上插入节点。
newEntry.next=current.next;
表[hash]=newEntry;
返回;
}否则{
newEntry.next=current.next;
previous.next=newEntry;
返回;
}
}
先前=当前;
当前=当前。下一步;
}
previous.next=newEntry;
}
}
/**
*方法返回与键对应的值。
*
*@param-key
*/
公共V get(K键){
int hash=散列(键);
if(表[hash]==null){
返回null;
}否则{
Entry temp=表[hash];
while(temp!=null){
如果(温度键等于(键))
返回温度值;
temp=temp.next;//返回键对应的值。
}
return null;//如果找不到键,则返回null。
}
}
/**
*方法从HashMapCustom中删除键值对。
*
*@param-key
*/
公共布尔删除(K deleteKey){
int hash=hash(deleteKey);
if(表[hash]==null){
返回false;
}否则{
前一项=空;