我对链表多图的删除功能有什么问题?

时间:2019-02-09 14:19:22

标签: java multimap

我正在使用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>”消息,用于删除键和值测试。

0 个答案:

没有答案