Search code examples
javaalgorithmdata-structureslinked-listbag

Bag remove() method


I was given Bag class like this

    import java.util.Iterator;
    import java.util.NoSuchElementException;

    public class Bag<Item> implements Iterable<Item> {

    private int N;               // number of elements in bag
    private Node<Item> first;    // beginning of bag

    // helper linked list class
    private class Node<Item> {
    private Item item;
    private Node<Item> next;
    }

    /**
    * Initializes an empty bag.
     */
    public Bag() {
    first = null;
    N = 0;
    }

    /**
     * Is this bag empty?
    * @return true if this bag is empty; false otherwise
     */
    public boolean isEmpty() {
    return first == null;
    }

    /**
     * Returns the number of items in this bag.
     * @return the number of items in this bag
     */
    public int size() {
    return N;
    }

    /**
     * Adds the item to this bag.
     * @param item the item to add to this bag
     */
    public void add(Item item) {
    Node<Item> oldfirst = first;
    first = new Node<Item>();
    first.item = item;
    first.next = oldfirst;
    n++;
}

    public void remove(Item item){ 
    // currentNode is the reference to the first node in the list and to the Item
    Node<Item> currentNode = first; 
    // if items equals the first node in the list, then first = currentNode.next which will make the first item 
    Node<Item> temp = currentNode;
    while(temp.next != null){
        temp = currentNode;
        if(item.equals(currentNode.item)){
            currentNode = currentNode.next;
            temp.next = currentNode;
            break;
        }else{
            currentNode = currentNode.next;
        }
    }
    N--; 
}

/**
 * Returns an iterator that iterates over the items in the bag in arbitrary order.
 * @return an iterator that iterates over the items in the bag in arbitrary order
 */
public ListIterator<Item> iterator()  {
    return new ListIterator<Item>(first);  
}

// an iterator, doesn't implement remove() since it's optional
private class ListIterator<Item> implements Iterator<Item> {
    private Node<Item> current;

    public ListIterator(Node<Item> first) {
        current = first;
    }

    public boolean hasNext()  { return current != null;                     }
    public void remove()      { throw new UnsupportedOperationException();  }

    public Item next() {
        if (!hasNext()) throw new NoSuchElementException();
        Item item = current.item;
        current = current.next; 
        return item;
    }
}

As it can be seen,remove() method is an optional therefore it doesn't include the algorithm.

I wrote the remove method like this:

public void remove(Item item)      { 
        Node<Item> currentNode = (Node<Item>) first;
        Node<Item> previousNode = null;
        while(currentNode != null){
            if(item.equals(currentNode.item)){
                if(previousNode  == null) {
                  first = (Node<Item>) currentNode.next;
                }
                else {
                  previousNode.next = currentNode.next;
                }
                n--;
            }
            else {
              previousNode = currentNode;
            }
            currentNode = currentNode.next;
        }

    }

However,

first = (Node<Item>) currentNode.next;

this line gives an "Type mismatch:Cannot convert from Bag.Node to Bag.Node" error which confuses me.

What should be done to overcome this error or is there a missing part in my remove method?


Solution

  • public class Bag<Item> implements Iterable<Item> {
      // ...
      private class Node<Item> {
        // ...
      }
      // ...
    }
    

    This is defining two distinct type variables, both with the name Item.

    If you want instances of Node to use the same type variable as the containing instance of Bag, remove the <Item> on Node:

    private class Node {