Я пытаюсь обновить элемент узла, выполнив поиск старого элемента и заменив его новым. Но есть ошибка, которую я не понимаю. Что заставляет мой код выдавать эту ошибку и как ее исправить? Ошибка;

The method update(Integer, Integer) is ambiguous for the type CircularLinkedList<Integer>

`

public class MainClass {

public static void main(String[] args) {
    CircularLinkedList<Integer> ccl = new CircularLinkedList<>();
    ccl.append(10);
    ccl.append(20);
    ccl.append(30);
    ccl.append(40);
    ccl.append(50);
    ccl.append(71);
    ccl.update(20, 25);

    System.out.println(ccl);
    
    }

}

Вот связанный метод;

public void update(E oldElement, E newElement) {
    Node<E> temp = head;
    while (temp.getElement() != oldElement) {
        temp = temp.next;
    }
    temp.setElement(newElement);
}

А вот и весь класс для лучшего понимания;

public class CircularLinkedList<E> {

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

    public Node(E e, Node<E> n) {
        element = e;
        next = n;
    }

    public E getElement() {
        return element;
    }

    public void setElement(E e) {
        element = e;
    }

    public Node<E> getNext() {
        return next;
    }

    public void setNext(Node<E> n) {
        next = n;
    }
}

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

public CircularLinkedList() {
};

public void addToHead(E e) {
    Node<E> newHead = new Node<E>(e, head);
    head = newHead;
    tail.setNext(newHead);
    size++;
}

public void append(E e) {
    if (head == null) {
        head = new Node<E>(e, null);
        tail = head;
        size++;
        return;
    }

    Node<E> temp = head;
    while (temp != tail) {
        temp = temp.next;
    }
    Node<E> newNode = new Node<E>(e, null);
    temp.next = newNode;
    tail = newNode;
    tail.setNext(head);
    size++;
    return;
}

public void append(E e, int index) {
    if (index % size == 0) {
        addToHead(e);
    }
    if (index % size == 1) {
        append(e);
    }
    Node<E> temp = head;
    for (int i = 0; i < (index - 1) % size; i++) {
        temp = temp.next;
    }
    Node<E> newNodesNext = temp.next;
    temp.setNext(new Node<E>(e, newNodesNext));
    size++;
}

public void update(E oldElement, E newElement) {
    Node<E> temp = head;
    while (temp.getElement() != oldElement) {
        temp = temp.next;
    }
    temp.setElement(newElement);
}

public void update(E e, int index) {
    if (size == 0) {
        throw new RuntimeException("Can not update anything in a empty list.");
    }
    Node<E> temp = head;
    for (int i = 0; i < (index - 1) % size; i++) {
        temp = temp.next;
    }
    temp.setElement(e);
}

public void remove(E e) {
    Node<E> temp = head;
    while (temp.next.getElement() != e) {
        temp = temp.next;
    }
    Node<E> nodeToBeRemoved = temp.next;
    temp.setNext(temp.next.next);
    nodeToBeRemoved.setNext(null);
    size--;
}

public String toString() {
    StringBuilder sb = new StringBuilder();
    Node<E> temp = head;
    for (int i = 0; i < size; i++) {
        sb.append(temp.getElement()).append(", ");
        temp = temp.next;
    }
    return sb.toString();
}

}

3
user13278163 15 Окт 2021 в 19:30

2 ответа

Лучший ответ

Это потому, что у вас есть два метода, называемых update. Один - update(E oldElement, E newElement), другой - update(E e, int index).

В случае, если E имеет тип Integer, обе сигнатуры метода совпадают. update(E oldElement, E newElement) рассматривается здесь как потенциальное совпадение, потому что примитив 25 в ccl.update(20, 25); может быть автоматически упакован в Integer. (20 автоматически упаковывается в оба метода)

Решением было бы переименовать один из ваших методов. Например, от update(E e, int index) до updateAtIndex(E e, int index).

Вы также можете явно привести первый аргумент к Integer. Этого достаточно, чтобы указать компилятору, какой метод вы хотите: ccl.update((Integer)20, 25);, в этом случае будет вызван update(E e, int index).

Как ни странно, приведение только второго аргумента к Integer не будет работать, и компилятор все равно выдаст ошибку «Неоднозначный вызов метода». Например. ccl.update(20, (Integer)25) недостаточно, чтобы указать компилятору, какой метод вам нужен. Я предполагаю, что в этом случае это связано с тем, что первый аргумент подлежит упаковке, поэтому второй аргумент также можно распаковать, но я не могу сказать наверняка.

3
QBrute 15 Окт 2021 в 17:34

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

-2
Jose Antonio Dominguez Garcia 15 Окт 2021 в 16:34