Search code examples
javalinked-listsingly-linked-listcircular-list

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


i am trying to update an element of node, by searching the old element and replace it with the new one. But there is an error that i dont understand. What leads my code to give that error and how do i fix it ? Error;

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);
    
    }

}

Here is the related method;

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

And here is the all class for better understanding;

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();
}

}


Solution

  • This is because you have two methods called update. One is update(E oldElement, E newElement) the other is update(E e, int index).

    In the case of E being of type Integer, both method signatures match. update(E oldElement, E newElement) is seen as a potential match here, because the primitive 25 in ccl.update(20, 25); can be auto-boxed to Integer. (The 20 is auto-boxed in both methods)

    A solution would be to rename one of your methods. For example update(E e, int index) to updateAtIndex(E e, int index).

    You can also explicitly cast the first argument to Integer. That's enough to tell the compiler which method you want: ccl.update((Integer)20, 25);, In that case update(E e, int index) will be called.

    Weirdly enough, casting only the second argument to Integer won't work and the compiler will still give you the "Ambiguous method call" error. E.g. ccl.update(20, (Integer)25) is not enough to tell the compiler which method you want. I assume in that case it's because the first argument is subject to boxing, so the second argument is still able to be unboxed as well but I can't say for sure.