我一直在编写自己的HashMap一段时间了。一切顺利,直到我停止编写“put”方法。我不确定我的rehash方法是否导致测试用例失败,或者它是否是我的实际put方法。我使用的测试用例来自JUnit库。我用来存储地图值的数据结构是MyMapEntry对象的数组(这实现了Entry类,我将为它提供代码)。我已将所有相关代码包含在此问题中。
入门级:
class MyMapEntry implements Entry<K,V>{
private K key;
private V value;
public MyMapEntry(K k) {
key = k;
}
public MyMapEntry(K k, V v) {
this(k);
value = v;
}
@Override
public K getKey() {
return key;
}
@Override
public V getValue() {
return value;
}
@Override
public V setValue(V v) {
V oldValue = value;
value = v;
return oldValue;
}
public boolean equals(MyMapEntry bob) {
return key.equals(bob.key);
}
}
put方法:
@Override
public V put(K key, V value) {
for (int i = 0; i < entryArray.length; i++) {
MyMapEntry entryInArray = entryArray[i];
if (entryInArray != null) {
if (entryInArray.getKey().hashCode() == entry.getKey().hashCode()) {
entryInArray.setValue(value);
return value;
}
}
}
if (entryArray[index] != null) { // Rehash if there is a collision
rehash();
index = entry.hashCode() % size;
}
entryArray[index] = entry;
actualSize++;
return value;
}
这是我编写的rehash算法。我不完全确定它写得正确:
private void rehash() {
entryArray = Arrays.copyOf(entryArray, entryArray.length * 2);
MyMapEntry[] tempArray = Arrays.copyOf(entryArray, entryArray.length);
Arrays.fill(entryArray, null);
for (int i = 0; i < tempArray.length; i++) {
MyMapEntry entry = tempArray[i];
if (entry != null) {
int index = entry.hashCode() % tempArray.length;
entryArray[index] = entry;
}
}
size = entryArray.length;
}
这是实际构建我创建的数据结构的测试方法:
public HashMapAPlus<MyDumbyData, String> buildReHashHashMap(int l){
HashMapAPlus<MyDumbyData, String> bob = new HashMapAPlus<>(l);
MyDumbyData d = new MyDumbyData("Bobby", Color.red);
bob.put(d, "Love ya");
d = new MyDumbyData("Ralph", Color.blue);
bob.put(d, "Snake");
d = new MyDumbyData("Blake", Color.black);
bob.put(d, "Something");
d = new MyDumbyData("Roman", Color.white);
bob.put(d, "Something else");
d = new MyDumbyData("Sam", Color.magenta);
bob.put(d, "Nothing much");
d = new MyDumbyData("Victor", Color.cyan);
bob.put(d, "Something more");
d = new MyDumbyData("Nick", Color.yellow);
bob.put(d, "Don't know");
d = new MyDumbyData("Frank", Color.orange);
bob.put(d, "Not sure");
d = new MyDumbyData("Aaron", Color.green);
bob.put(d, "Not at all");
d = new MyDumbyData("Brit", Color.red);
bob.put(d, "Not sure what");
return bob;
}
“MyDumbyData”应该代表每个测试用例的hashmap中的每个键。这是类代码:
public class MyDumbyData {
private String name;
private Color color;
public MyDumbyData(String n, Color c) {
name = n;
color = c;
}
public String getName() {
return name;
}
public Color getColor() {
return color;
}
public boolean equals(MyDumbyData dd) {
return name.equals(dd.getName()) && color.equals(dd.getColor());
}
public int hashCode() {
return name.hashCode() + color.hashCode();
}
public String toString() {
return name+": "+color.toString();
}
}
最后,这是失败的测试用例:
@Test
public void testAddGet1() {
HashMapAPlus<MyDumbyData, String> bob = this.buildReHashHashMap(10);
assertEquals(10, bob.size());
MyDumbyData d = new MyDumbyData("Bobby", Color.red);
assertEquals("Love ya", bob.get(d)); // This is where the first assertion error is.
d = new MyDumbyData("Ralph", Color.blue);
assertEquals("Snake", bob.get(d));
d = new MyDumbyData("Blake", Color.black);
assertEquals("Something", bob.get(d));
d = new MyDumbyData("Roman", Color.white);
assertEquals("Something else", bob.get(d));
d = new MyDumbyData("Sam", Color.magenta);
assertEquals("Nothing much", bob.get(d));
d = new MyDumbyData("Victor", Color.cyan);
assertEquals("Something more", bob.get(d));
assertNull(bob.getLinkedListArray());
assertNotNull(bob.getMapEntryArray());
}
请注意,如果第一个断言错误发生的行被注释掉,则测试用例通过。
如果我提供了太多代码,我道歉。只是所有这些代码都用于最终结果。
感谢所有帮助 - 鲍勃
答案 0 :(得分:1)
不幸的是,您需要查看很多错误:
put
实现正在遍历所有地图条目。使用散列的重点是使用它们来索引数组。我可以看到其他许多问题。但我建议您采用不同的方法来构建和调试代码。您正陷入编写所有代码的陷阱,然后构建一个测试所有内容的复杂测试用例。代替: