Java中Map集合的自定义实现



我正在尝试创建一个Map集合的实现,该集合存储一对键和值项。该错误发生在运行时,当我尝试注册键值对并点击此行时。

EntryNode<K, V> mapEntry = mapEntryList[mapSize];

我对这个问题已经没有什么想法了,任何帮助都很感激。谢谢

//Driver class to test output
public class Driver{
public static void main(String[] args) {
MyMap<String, String> mapInstance = new MyMap<String, String>();
myMap.register("Key1", "Value");

System.out.println(myMap.get("Key1"));

}
}

public class MyMap<K, V> implements MapInterface<K, V>{

private EntryNode<K, V>[] mapEntryList;
private int mapSize = 0;

public MyMap(){

}

public MyMap(int capacity){
this.mapEntryList = new EntryNode[mapSize];
}

//static
public class EntryNode<K, V>{
K keyElement;
V valueElement;
EntryNode<K, V> nextMapEntry;
public EntryNode(K keyElement, V valueElement, EntryNode<K, V> nextMapEntry) {
this.keyElement = keyElement;
this.valueElement = valueElement;
this.nextMapEntry = nextMapEntry;
}
public K getKey() {
return keyElement;
}
public V getValue() {
return valueElement;
}
public EntryNode<K, V> getNextMapEntry() {
return nextMapEntry;
}

public final V setNewValue(V newValueElement) {
V oldValueElement = valueElement;
valueElement = newValueElement;
return oldValueElement;
}

public String toString() {
return "{" + keyElement + ", " + valueElement + "}";
}
}

public int size() {
return mapSize;
}

public V get(K keyElement) {
EntryNode<K, V> mapEntry = mapEntryList[mapSize];
int count = mapSize;
boolean entryPresent = false;

EntryNode tempNode = firstEntry;
while (!entryPresent && mapEntry != null) {
if (keyElement == mapEntry.keyElement) {
entryPresent = true;
return mapEntry.valueElement;
} 
else {
mapEntry = mapEntry.nextMapEntry;
}
}
return null;
}
public void register(K newKeyElement, V newValueElement) { 
EntryNode<K, V> newEntry = new EntryNode(newKeyElement, newValueElement, null);
EntryNode<K, V> mapEntry = mapEntryList[mapSize];
boolean entryPresent = false;

while (!entryPresent && mapEntry != null) {
if (newKeyElement == mapEntry.keyElement) {
entryPresent = true;
break;
} 
else {
if(mapEntry.nextMapEntry == null){
break;
}
mapEntry = mapEntry.nextMapEntry;
}
}
if(!entryPresent){
mapEntry.nextMapEntry = newEntry;
mapSize++;
}
}

public void remove(K removeKeyElement) {
EntryNode previousEntry = null;
EntryNode<K, V> mapEntry = mapEntryList[mapSize];
while (mapEntry != null) {
if (removeKeyElement == mapEntry.keyElement) {
mapEntry.keyElement = null;
mapEntry.valueElement = null;
previousEntry.nextMapEntry = mapEntry.nextMapEntry;
break;
} 
else {
previousEntry = mapEntry;
mapEntry = mapEntry.nextMapEntry;
}
}
}

private int getEntriesSize() {
return mapEntryList.length;
}
public String toString() {
StringBuilder stringOutput = new StringBuilder();
for (EntryNode entry : mapEntryList) {
stringOutput.append("[");
while (entry != null) {
stringOutput.append(entry);
if (entry.nextMapEntry != null) {
stringOutput.append(", ");
}
entry = entry.nextMapEntry;
}
stringOutput.append("]");
}
return "{" + stringOutput.toString() + "}";
}   
}

假设我制作了一个新地图,然后对其调用.get((。

MyMap<Integer, String> m = new MyMap<>();
m.get(5);

这个构造函数(无参数构造函数(意味着从未设置mapEntryList,这意味着它默认为null。因此,当调用get时,get方法所做的第一件事就是取消引用mapEntryList字段(foo[idx]构造取消引用foo(。取消引用null值意味着:抛出NullPointerException。很明显,如果键不在映射中,那么代码的目的是返回null,因此,该部分已损坏。

或者,我会选择:

MyMap<Integer, String> m = new MyMap<>(10);
m.get(5);

这一次,我调用了第二个构造函数。此构造函数获取"capacity"值,将其扔进垃圾桶,并生成一个0大小的数组。然后,调用get,然后运行您的代码:

mapEntry = mapEntryList[mapSize];

这是行不通的;您无法从0长度的数组中获取任何内容。事实上,如果你写:

int[] a = new int[5];
a[5];

(在中,您创建一个大小为X的新数组,然后要求使用索引为X的元素(,您总是得到一个IndexOutOfBoundsException:在java中,所有数组都是0索引的。a[0]是第一个元素,而new int[1]生成一个1大小的int数组,因此在1大小的数组上执行a[1](请求第二个元素(是不可能的(它只有一个元素(。

这个代码还有大约50个其他问题,你真的需要一步一个脚印地调试这个代码:与其只看所有这些代码然后说:嗯,它不起作用-你需要调试它:

写一些代码,然后运行它。当你运行它时,"在脑海中运行它":如果必须的话,拿着笔和纸,一行一行地遍历代码,用手弄清楚每一行应该做什么。然后,通过使用调试器或在必要时添加大量System.out语句,检查你认为应该发生的事情与实际发生的事情。在哪里,代码会做一些与你想象的不同的事情?你发现了一个错误。可能是一大堆名单中的第一个。修复它,并继续进行,直到bug消失。

最新更新