Singly linked list node not able to be cast as Integer

我的未来我决定 提交于 2019-12-14 03:24:47

问题


I am writing a generic singly linked list as a homework assignment. I have been given the JUnit test that the instructor is going to use to test the code. When I run the test, gives me this error: java.lang.ClassCastException: SinglyLinkedList$Node cannot be cast to java.lang.Integer. If I am using a generic as the type, why can't I cast it as an Integer?

Also, when I first ran the test, the bash showed: JUnit version 4.12 .E.E.E. And it stayed like this until I ended the process. I think this may be a sign of an infinite loop, but even looking at my code, I can't find where it would be infinite.

This is my SinglyLinkedList class

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

public class SinglyLinkedList<E> implements Iterable<E>{

    private Node<E> head;
    private Node<E> tail;

    public SinglyLinkedList() {
        head = new Node<E>(null, tail);
        tail = new Node<E>(null, null);
    }

    /**
     * Insert at the end of the list
     * @param E
     */
    public void add(E element) {
        Node<E> place = head;
        if(head.getNext() == null){
            Node node = new Node(element,tail);
            head.setNext(node);
        }
        else{while(place.next != tail){
            place = place.getNext();
            Node node = new Node(element, tail);
            place.setNext(node);
            }
        }
    }

    /**
     * Remove element from the list
     * @param E
     */
    public void remove(E element){
        Node place = head;
        Node prev = head;
        while(place.getElement() != element){
            prev = place;
            place = place.getNext();
        }
        prev.setNext(place.getNext());
    }

    /**
     * Clear all elements
     */
    public void clear(){
        head.setNext(null);
    }

    /**
     * Gets the Nth to last node
     * @param int n
     * @return E
     */
    public E getNthToLast(int n){
        int length = 0;
        Node temp = head;
        while(temp.getNext() != tail){
            temp = temp.getNext();
            length++;
        }
        if(length < n){
            throw new NoSuchElementException();
        }
        temp = head;
        for(int i = 0; i < length - n+1; i++){
            temp = temp.getNext();
        }
        return (E) temp.getElement();
    }
    /**
     * Creates new Iterator
     * @return SinglyLinkedListIterator
     */
    @Override
    public SinglyLinkedListIterator iterator(){
        return new SinglyLinkedListIterator();
    }

    private class Node<E> {
        private E element;
        private Node<E> next;

        public Node(E element, Node next) {
            this.element = element;
            this.next = next;
        }

        public void setNext(Node next){
            this.next = next;
        }
        public Node getNext(){
            return this.next;
        }
        public void setElement(E element){
            this.element = element;
        }
        public E getElement(){
            return this.element;
        }

    }

    public class SinglyLinkedListIterator implements Iterator<E> {
        private Node curr = head;
        Node prev = head;

        /**
         * Gets the next node 
         * @return E
         */
        @Override
        public E next() {
            if(curr.getNext() != tail){
                prev = curr;
                curr = curr.getNext();
                return (E) curr;
            }
            else{
                throw new NoSuchElementException();
            }
        }
        @Override
        public boolean hasNext() { 
            if(curr.getNext() != null){
                return true;
            }
            else{return false;}
        }
        @Override
        public void remove() {
            if(curr != tail){
                prev.setNext(curr.getNext());
            }else{throw new IllegalStateException();}
        }
        public void add(E element){
            Node node = new Node(element, curr.getNext());
            curr.setNext(node);
        }
    }
}

This is the JUnit test:

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

import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.Before;
import org.junit.Rule;
import org.junit.rules.ExpectedException;

public class TestLinkedList{
  private SinglyLinkedList<Integer> list;

  @Rule // this rule allows one of the tests to verify that an exception is thrown
  public ExpectedException thrown = ExpectedException.none();

  @Before
  public void setUp(){
    list = new SinglyLinkedList<>();
    SinglyLinkedList<Integer>.SinglyLinkedListIterator it = list.iterator();
    for(int i = 9; i > 0; i--){
      it.add(new Integer(i));
      it.next();
    }
    // Question to all: The process of adding numbers to the list could
    // have been simplified by dispensing with the iterator and simply
    // calling SinglyLinkedList's add() method. Why use the iterator?
    // What benefit does it provide over SinglyLinkedList's add?
  }

  /**
  * Ensure that the linked list holds the expected values after the
  * initialization in the setup() method. This initialization used the
  * list iterator to perform the adds.
  */
  @Test
  public void testIteratorAdd(){
    Iterator<Integer> it = list.iterator();
    Integer listElement;
    for(int i = 9; i > 0; i--){
      listElement = it.next();
      assertEquals(i, listElement.intValue());
    }
  }

  /**
  * Ensure that the list is built correctly if the list's add method is
  * used instead of the iterator's add method.
  */
  @Test
  public void testListAdd(){
    list.clear();
    for(int i = 9; i > 0; i--){
      list.add(new Integer(i));
    }
    Iterator<Integer> it = list.iterator();
    Integer listElement;
    for(int i = 9; i > 0; i--){
      listElement = it.next();
      assertEquals(i, listElement.intValue());
    }
  }

  /**
  * Remove all the odd numbers using the list's remove method and ensure
  * that the remaining elements are as expected (the even numbers 8, 6,
  * 4, and 2).
  */
  @Test
  public void testListRemove(){
    list.remove(9);
    list.remove(7);
    list.remove(5);
    list.remove(3);
    list.remove(1);

    Iterator<Integer> it = list.iterator();
    int evenNum = 8;
    while(it.hasNext()){
      assertEquals(evenNum,it.next().intValue());
      evenNum = evenNum - 2;
    }
  }

  /**
  * Remove all the even numbers using the iterators's remove method and ensure
  * that the remaining elements are as expected (the odd numbers 9, 7,
  * 5, 3, and 1).
  */
  @Test
  public void testIteratorRemove(){
    // first, remove all the even numbers
    Iterator<Integer> it = list.iterator();
    while(it.hasNext()){
      Integer theVal = it.next().intValue();
      if( theVal.intValue() % 2 == 0){
        it.remove();
      }
    }
    // Next, check that the list contains the correct
    // remaining numbers
    it = list.iterator();
    int oddNum = 9;
    while(it.hasNext()){
      assertEquals(oddNum,it.next().intValue());
      oddNum = oddNum - 2;
    }
  }

  /**
  * Attempt to remove from an empty list and ensure that the
  * IllegalStateException is thrown
  */
  @Test
  public void testEmptyRemove(){
    list.clear();
    thrown.expect(IllegalStateException.class);
    Iterator<Integer> it = list.iterator();
    it.remove();
  }

  /**
  * Attempt to call next() when already at the end of the list and
  * ensure that the NoSuchElementException is thrown.
  */
  @Test
  public void testInvalidNext(){
    list.clear();
    thrown.expect(NoSuchElementException.class);
    Iterator<Integer> it = list.iterator();
    it.next();
  }

  /**
  * Test the getNthToLast method. 
  *
  * As an example, given the numbers that is list holds:
  * 9 8 7 6 5 4 3 2 1
  * the 2nd to last element is 2, the 3rd to last
  * is 3, and so on.
  *
  * Ensure that the getNthToLast returns 4 when requested the 4th to
  * last element.
  */
  @Test
  public void testGetNthToLast(){
    Integer ans = list.getNthToLast(4);
    assertEquals(new Integer(4),ans);
  }
}

回答1:


Code cleanup

You have a lot of raw types, which complicate finding the broken code, you want to explicity say that Nodes are Node<E>s.

Main issue

return (E) curr;

You are returning the node and trying to cast it, causing problems, it should be:

return curr.element;


来源:https://stackoverflow.com/questions/46476547/singly-linked-list-node-not-able-to-be-cast-as-integer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!