Java - ошибка, связанная с обобщениями

1

У меня есть класс и внутренний класс, которые работают вместе, чтобы создать связанный список. Данные, хранящиеся в узлах, являются родовыми, а я где-то рядом с моим кодом, я напортачил с участием дженериков, но я не знаю, где. Я получаю 5 ошибок, первый говорит: "Тип LinkedList не принимает параметры", который, по моему мнению, странный, потому что LinkedList - это просто интерфейс, который я реализую. Остальные из них сформулированы "Объект не может быть преобразован в E". Я отметил, где они происходят. Я понял, что мое задание правильно, я не знаю, что случилось. Если вы хотите, чтобы я опубликовал интерфейс LinkedList, дайте мне знать.

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

    private Node head;
    private Node tail;
    private int size;

    public SinglyLinkedList(){
        this.head = null;
        this.tail = null;
        this.size = 0;
    }


     public E get(int index) {
         //Hold the data of the cur node
         //and keep iterating until you hit the
         //right index
         int hit = 0;
         Node pos = this.head;
         E found = this.head.data;//////ERROR HERE
         while (hit < index) {
             pos = pos.next;
             found = pos.data;//////ERROR HERE   
             hit++;
         }
         return found;
     }

     public void add (E data) {
         Node last = new Node(data, null);
         //If the list is empty. 
         if (this.head == null) {
             this.head = last;
         }
         //Make the cur tail next the new node
         //and set the new node as the new tail.
         this.tail.next = last;
         this.tail = last;
         this.size++;
     }

     public boolean add(int index, E data) {
         //Cannot add if index is not valid
         if ((index >= this.size) || (index < 0) ) {
             return false;
         }
         //If index is 0, add at beginning
         Node insert = new Node(data, null);
         if (index == 0) {
             insert.next = this.head;
             this.head = insert;
             this.size++;    
             return true;
         } else { 
         //Else, go until you reach desired index then
         //Set whatever was at that index to the new Node's
         //next value.
             int hit = 1;
             Node cur = this.head;
             while (hit < index) {
                 cur = cur.next; 
                 hit++;
             }
             insert.next = cur;
             this.size++;
             return false;
         }
     }

     public void addAll(Collection<? extends E> c) {
         for (E item: c) {
             this.add(item);
         }

     }

     public boolean contains(E data) {
         int hit = 0;
         Node cur = this.head;
         Node move;
         while (hit < this.size) {
             if (data.equals(cur.data)) {
                 return true;
             } else {
                 move = cur.next;
                 cur = move;
             }
         }
         return false;
     }

     public boolean containsAll(Collection<? extends E> c) {
         for (E item: c) {
             if (!(this.contains(item))) {
                 return false;
             }
         }
         return true;
     }

     public boolean remove(E data) {
         Node prev = this.head;
         Node cur = this.head.next;
         int hit = 1;
         if (!(this.contains(data))) {
             return false;
         } else if (data.equals(head.data)) {
             this.head = cur;
             return true;
             this.size--;
         }
         while (hit < this.size) {
             if (data.equals(cur.data)) {
                 prev.next = cur.next;
                 return true;
                 this.size--;
             }
             hit++;
         }


     }

     public E remove(int index) {
         int hit = 1;
         E data;
         Node prev = this.head;
         Node cur = this.head.next;
         if (index == 0) {
             data = head.data; //////ERROR HERE
             this.head = cur;
             return data;
             this.size--;
         } else {
             while (hit < this.size) {
                 if ( hit == index) {
                     data = cur.data; //////ERROR HERE
                     prev.next = cur.next;
                     return data;
                     this.size--;
                 } else {
                     prev = cur;
                     cur = prev.next;
                     hit++;
                 }
             }
         }
     }

     public boolean removeAll(Collection<? extends E> c) {
         int prevSize = this.size;
         for (E item: c) {
             remove(item);
         }
         return (prevSize < this.size);
     }

     public int size() {
         return this.size;
     }

     public boolean isEmpty() {
         return (this.head == null);
     }

     public void clear() {
         this.head = null;
         this.tail = null;
         size = 0;
     }


    private class Node<E> {

        private E data;
        private Node next;

        private Node(E data, Node next) {
            this.data = data;
            this.next = next;
        }   
    }
}

Это класс интерфейса

/**
 * The LinkedList interface defines a set of standard operations that are
 * typically associated with linked list, such as adding, removing, and checking
 * to see if the list contains an item.
 *
 * Note that while your linked list implementation should make use of a Node
 * class, the methods below take in and return instances of the generic type,
 * not the nodes themselves.
 *
 * @author Justin Nieto
 * @version 1.1
 * @param <E> the type of the elements to store in the linked list
 */
public interface LinkedList<E> {

    /**
     * Returns the element in the linked list at the specified index.
     * Does not change the contents of the list in any way. If the given
     * index is negative or greater than the maximum possible index, returns
     * null.
     *
     * @param index of element to be retrieved
     * @return the element at the given index or null if index out of bounds
     */
    E get(int index);

    /**
     * Adds the specified piece of data to the end of the linked list.
     * This method should execute in O(1) (constant) time. This means that
     * you should not iterate over the whole list to add the item to the end
     * (we will check for this).
     *
     * @param data the object to be added to the linked list
     */
    void add(E data);

    /**
     * Adds given piece of data to the linked list at the given index.
     * All items that were originally at the index or after the index should
     * be shifted down by one. If the index specified is not valid, returns
     * false. Otherwise, returns true.
     *
     * If the index specified is 0 or if it is one larger than the maximum
     * current index (ie if index is equal to the size of the linked list),
     * then this method should execute in O(1) (constant) time. This means that
     * you should not iterate over the entire list to add the element, as it
     * is unnecessary to do so.
     *
     * @param index the index at which to add the item
     * @param data the item to be added to te linked list
     * @return true if the data could be added at the given index
     */
    boolean add(int index, E data);

    /**
     * Adds each element in the Collection to the end of the linked list.
     *
     * @param c the collection of items to add to the end of the linked list
     */
    void addAll(Collection<? extends E> c);

    /**
     * Determines whether or not the given piece of data is in the linked list.
     *
     * @param data the item to check
     * @return true if the linked list contains the item, false otherwise
     */
    boolean contains(E data);

    /**
     * Determines whether or not every element of the given Collection is
     * in the linked list.
     *
     * @param c the Collection of elements to check
     * @return true if list contains every element in the Collection
     */
    boolean containsAll(Collection<? extends E> c);

    /**
     * Finds the first element of the list equal to the given piece of data
     * and removes it from the list. Returns false if the given piece of data
     * is not in the list and therefore cannot be removed.
     *
     * @param data the piece of data to be removed from the list
     * @return true if the item was removed, false if list does not contain it
     */
    boolean remove(E data);

    /**
     * Removes and returns the item in the list at the given index.
     * All items at indices after the given index are shifted down by one.
     *
     * @param index the index of the item to remove from the linked list
     * @return the removed item
     */
    E remove(int index);

    /**
     * Removes each element in the given collection from the linked list.
     *
     * @param c the Collection of items to remove
     * @return true if each element in the Collection was removed.
     */
    boolean removeAll(Collection<? extends E> c);

    /**
     * Returns the number of elements in the linked list. This method
     * should execute in O(1) (constant) time. This means that you should not
     * iterate over the entire list to count the number of items, but rather
     * you should maintain a size variable that you can just return here.
     *
     * @return the number of elements in the linked list
     */
    int size();

    /**
     * Returns true if the linked list has no elements.
     *
     * @return true if the list is empty, false otherwise
     */
    boolean isEmpty();

    /**
     * Removes all elements from the list. After calling this method,
     * the isEmpty method should return true.
     */
    void clear();

}
  • 0
    Одна проблема заключается в том, что вам нужно объявить все ваши экземпляры и параметры типа Node как Node<E> (даже в классе Node). Вам также следует опубликовать интерфейс LinkedList, так как одно из ваших сообщений об ошибках относится к этому.
  • 0
    Вы уверены, что не написали другой интерфейс LinkedList , у которого нет параметра типа?
Показать ещё 1 комментарий
Теги:
generics
linked-list
interface

1 ответ

1
Лучший ответ

Node является внутренним классом SinglyLinkedList, поэтому он уже разделяет параметр типа E Поэтому вы можете сделать Node неэквивалентным классом.

private class Node {

    private E data;
    private Node next;

    private Node(E data, Node next) {
        this.data = data;
        this.next = next;
    }   
}

Это устраняет многие проблемы, потому что до того, как Node был универсальным классом, и вы использовали Node без параметра типа.

Альтернативное решение - сделать Node статическим вложенным классом. Это означает, что экземпляр Node не принадлежит экземпляру SinglyLinkedList. Из-за этого для static версии Node потребуется собственный параметр типа.

private static class Node<E> {

    private E data;
    private Node<E> next;

    private Node(E data, Node<E> next) {
        this.data = data;
        this.next = next;
    }   
}

Обратите внимание, что в этой версии Node является общим, поэтому мне приходилось добавлять <E> после него каждый раз, когда он появился. Если вы идете со статическим подходом, вам нужно будет добавить <E> после каждого появления Node в остальной части класса. Их много.

Наконец, сообщение " LinkedList не принимает параметры" не требует пояснений. Предположительно, он говорит interface LinkedList когда он должен сказать interface LinkedList<E>.

  • 0
    Спасибо за четкое объяснение! Это исправило 4 ошибки, которые были одинаковыми. Знаете ли вы, как бы я исправил ошибку «Тип LinkedList не принимает параметры»?
  • 0
    Просто измените его на interface LinkedList<E> .
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню