Ошибка метода общего метода установки несовместимого типа - PullRequest
0 голосов
/ 11 октября 2018

Я новичок в дженериках и пытаюсь реализовать связанный список, используя родовой класс SinglyLinkedNode.Однако, когда я запускаю методы setData () и setNext (), я получаю следующую ошибку:

.\singlyLinkedList\SinglyLinkedNode.java:13: error: incompatible types: T#1 cannot be 
converted to T#2
this.data = d;
            ^
where T#1,T#2 are type-variables:
  T#1 extends Object declared in method <T#1>setData(T#1)
  T#2 extends Object declared in class SinglyLinkedNode
.\singlyLinkedList\SinglyLinkedNode.java:21: error: incompatible types: 
SinglyLinkedNode<T#1> cannot be converted to SinglyLinkedNode<T#2>
this.next = n;
            ^
where T#1,T#2 are type-variables:
  T#1 extends Object declared in method <T#1>setNext(SinglyLinkedNode<T#1>)
  T#2 extends Object declared in class SinglyLinkedNode

Мне кажется, что ошибка возникает из-за потенциального сценария, в котором типысуществующие ранее this.data или this.next не совпадают с d или n.Как я могу обойти это?Есть ли какой-нибудь способ, которым я могу переписать тип T # 1 (ранее существовавший элемент данных) с помощью T # 2 (новый элемент данных)?Вот класс с моим конструктором и моими методами установки:

public class SinglyLinkedNode<T> {
  private T data;
  private SinglyLinkedNode<T> next;

  SinglyLinkedNode(T d) {
    this.data = d;
    this.next = null;
  }

  public <T> void setData(T d) {
    this.data = d;
  }

  //...

  public <T> void setNext(SinglyLinkedNode<T> n) {
    this.next = n;
  }

  //...

}

Я ценю любую помощь, которую вы можете предложить.Заранее спасибо!

Редактировать: Спасибо за вашу помощь!Я удалил из своих методов, но по-прежнему получаю следующие ошибки при запуске setNext () из моего класса SinglyLinkedList:

.\singlyLinkedList\SinglyLinkedList.java:63: error: method setNext in class SinglyLinkedNode<T#2> cannot be applied to given types;
    curr.setNext() = toBeRemoved.getNext();
        ^
  required: SinglyLinkedNode<T#1>
  found: no arguments
  reason: actual and formal argument lists differ in length
  where T#1,T#2 are type-variables:
    T#1 extends Object declared in class SinglyLinkedList
    T#2 extends Object declared in class SinglyLinkedNode
.\singlyLinkedList\SinglyLinkedList.java:79: error: method setNext in class SinglyLinkedNode<T#2> cannot be applied to given types;
    prev.setNext() = this.head;
        ^
  required: SinglyLinkedNode<T#1>
  found: no arguments
  reason: actual and formal argument lists differ in length
  where T#1,T#2 are type-variables:
    T#1 extends Object declared in class SinglyLinkedList
    T#2 extends Object declared in class SinglyLinkedNode
.\singlyLinkedList\SinglyLinkedList.java:82: error: method setNext in class SinglyLinkedNode<T#2> cannot be applied to given types;
        prev.setNext() = curr.getNext();
            ^
  required: SinglyLinkedNode<T#1>
  found: no arguments
  reason: actual and formal argument lists differ in length
  where T#1,T#2 are type-variables:
    T#1 extends Object declared in class SinglyLinkedList
    T#2 extends Object declared in class SinglyLinkedNode

Так что мне кажется, что getNext () (из SinglyLinkedNode)и head (из SinglyLinkedList) не возвращают никаких значений, даже если они оба должны возвращать объекты SinglyLinkedNode.

Вот код, о котором идет речь.Я отметил, где возникают ошибки.

public class SinglyLinkedList<T> {
  private int size;
  private SinglyLinkedNode<T> head;
  private SinglyLinkedNode<T> tail;

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

  //...

  public SinglyLinkedNode<T> remove(int i) {
    SinglyLinkedNode<T> curr = this.head;
    for(int counter = 0; counter < i; counter++) {
      curr = curr.getNext();               //<---------------
    }
    SinglyLinkedNode<T> toBeRemoved = curr.getNext();
    curr.setNext() = toBeRemoved.getNext();
    this.size--;
    return toBeRemoved;
  }

  //...

  public SinglyLinkedNode<T> remove(T d) {
    if(this.head == null) {
      return null;
    }
    if(this.head.getData() == d) {
      SinglyLinkedNode<T> toBeRemoved = this.head;
      this.head = this.head.getNext();
      return toBeRemoved;
    }
    SinglyLinkedNode<T> curr = this.head;
    SinglyLinkedNode<T> prev = null;
    prev.setNext() = this.head;           //<---------------
    while(curr.getNext() != null) {
      if(curr.getData() == d) {
        prev.setNext() = curr.getNext();  //<---------------
        return curr;
      }
    }
    return null;
  }

  //...

Если кто-нибудь все еще сталкивается с этим сообщением, я был бы признателен, если бы они могли помочь мне с этим.Еще раз спасибо!

Редактировать: я также исправил эту ошибку;это

curr.setNext(toBeRemoved.getNext());

не

curr.setNext() = toBeRemoved.getNext()

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

Проблема, с которой вы сталкиваетесь, на самом деле очень проста.По сути, вы должны понимать, что универсальные методы полностью независимы от универсальных классов .

public <T> void setData(T d) {
this.data = d;
}

public <T> void setNext(SinglyLinkedNode<T> n) {
    this.next = n;
}

Когда вы помещаете <T> в модификатор метода, вы делаете его универсальным методом.Тип T в вашем универсальном методе отличается и переопределяет тип T всего класса. Это означает, что вы можете ввести объект любого типа, и метод будет использовать его в качестве локального значения T, которое может полностью отличаться от глобального.введите T.

Удаление <T> из ваших модификаторов методов сделает их обычными методами установки и по умолчанию будет соответствовать типу класса T, который гарантированно соответствует требуемому типу.

0 голосов
/ 11 октября 2018

Вам не нужно иметь дженерики для сеттеров, поскольку они будут заботиться о данных того же типа, что и класс.Итак, ваш код будет выглядеть так:

public class SinglyLinkedNode<T> {
    private T data;
    private SinglyLinkedNode<T> next;

    SinglyLinkedNode(T d) {
        this.data = d;
        this.next = null;
    }

    public void setData(T d) {
        this.data = d;
    }

    //...

    public void setNext(SinglyLinkedNode<T> n) {
        this.next = n;
    }

    //...

}

Итак, теперь вы можете создать экземпляр SinglyLinkedNode и установить значения как:

public static void main(String[] args) {
    SinglyLinkedNode<Integer> integers = new SinglyLinkedNode<>(2);
    // 
}

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

...