我正在使用Java中的linkedlist
实现多图。但是两个remove方法和replace方法出了点问题。我用Junit测试了这三种方法,它们都通过了,但无法通过平地机。
该实现使用两种类型的节点:
MapNode
:这些节点将用于存储键和对该键关联值的链接列表的引用。
ValueNode
:这些节点将用于存储与键关联的值。
下图显示了LinkedList_Multimap的结构。 https://imgur.com/a/EUD4DeE
/* Replaces the entry for the specified key only if currently mapped to the
* specified value.
*
* Throws: NullPointerException - if the specified key or
* oldValue or newValue is null.
* IllegalStateException - if the key is not
* in the multimap, or oldValue is not already associated with key; or if
* oldValue and newValue are the same.
*
* @param key - key with which the specified value is associated
* @param oldValue - value expected to be associated with the specified key
* @param newValue - value to be associated with the specified key
* @return true if the value was replaced
*/
@Override
public boolean replace(K key, V oldValue, V newValue)
{
if(key==null || oldValue == null || newValue==null)
throw new NullPointerException("Something is null!");
if(oldValue.equals(newValue))
throw new IllegalStateException("Old and new values are the same!");
if(head == null || head.getValues() == null) return false;
MapNode<K, V> curr = head;
while(!curr.getKey().equals(key)){
if(curr.getNext()==null){ //no existing key
throw new IllegalStateException("The key is not in the multimap!");
}
curr = curr.getNext();
}
ValueNode<V> currV = curr.getValues();
if(currV.getValue().equals(oldValue)) {
ValueNode<V> newV = new ValueNode<>(newValue);
curr.setValues(newV);
newV.setNext(currV.getNext());
return true;
}
ValueNode<V> preV =null;
while(!currV.getValue().equals(oldValue)){
if(currV.getNext()==null){ //no existing old value
throw new IllegalStateException("The value is not associated with the key!");
}
if(curr.getNext()!= null && curr.getNext().getValues().equals(oldValue)) {
preV = new ValueNode<>(newValue);
}
currV = currV.getNext();
}
ValueNode<V> newV = new ValueNode<>(newValue);
if(preV==null) {
curr.setValues(newV);
}
else {
preV.setNext(newV);
}
newV.setNext(currV.getNext());
return true;
}
->我从替换测试中得到了NullPointerException。
/*
* Removes the mapping for a key from this map if it is present. The key and
* its associated values are removed. Throws:
* NullPointerException - if the
* specified key is null.
* IllegalStateException - if key is not in the
* multimap
*
* @param key
* - key whose mapping is to be removed from the multimap
* @return the head of the list of values mapped to the key or null if the map contained
* no mapping for the key
*/
@Override
public ValueNode<V> remove(Object key)
{
if(key == null)
throw new NullPointerException("The key is null!");
if(head == null)
return null;
MapNode<K, V> curr = head;
if(curr.getKey().equals(key)) {
head = curr.getNext();
curr.setNext(null);
size --;
return curr.getValues();
}
MapNode<K, V> prev = null;
while(!curr.getKey().equals(key)){
if(curr.getNext()==null){ //no existing key
throw new IllegalStateException("The key is not in the multimap!");
}
if(curr.getNext()!= null && curr.getNext().getKey().equals(key)) {
prev = curr;
}
curr = curr.getNext();
}
prev.setNext(curr.getNext());
curr.setNext(null);
size--;
return curr.getValues();
}
->我收到“预期<2>,但收到<3>”消息以删除密钥测试。
/*
* Removes the entry for the specified key only if it is currently mapped to
* the specified value. value is removed from the list of values. If value
* is the only value associated with key, then key is also removed.
* Throws:
* NullPointerException - if the specified key or value is null.
* IllegalStateException - if key is not in the multimap.
* key is not removed if it is not mapped with value
*
* @param key
* - key with which the specified value is associated
* @param value
* - value expected to be associated with the specified key
* @return true if the value was removed.
*/
@Override
public boolean remove(Object key, Object value)
{
if(key == null || value == null)
throw new NullPointerException("The key or the value is null!");
if(head == null)
return false;
MapNode<K, V> curr = head;
while(!curr.getKey().equals(key)){
if(curr.getNext()==null){ //no existing key
throw new IllegalStateException("The key is not in the multimap!");
}
curr = curr.getNext();
}
// if(curr.getValues()==null)
// return false;
ValueNode<V> currV = curr.getValues();
ValueNode<V> preV = null;
if(currV.getValue().equals(value)) {
if(currV.getNext()==null) {
remove(key);
return true;
}
curr.setValues(currV.getNext());
currV.setNext(null);
return true;
}
while (!currV.getValue().equals(value)) {
if(currV.getNext()==null)
return false;
if( currV.getNext()!= null && currV.getNext().getValue().equals(value))
preV = curr.getValues();
currV = currV.getNext();
}
preV.setNext(currV.getNext());
currV.setNext(null);
return true;
}
->我收到了“预期<3>但是<5>”消息,用于删除键和值测试。