0

I'm implementing a list link in the stack. The program successfully passes all the required tests, but I encounter this warning. There is no disruption in the implementation of the program, but I am looking to eliminate this problem.

Can you tell me how to fix it by editing the code in the Equals method?

Unchecked cast: 'java.lang.Object' to 'LinkedStack'

public final class LinkedStack<E> implements Stack<E> {

    private Node head = null;
    private int size = 0;

    @Override
    public int size() {
        return size;
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public void clear() {
        head = null;
        size = 0;
    }

    @Override
    public boolean contains(E e) {
        for (int i = 0; i < size; i++) {
            E temp = pop();
            if (temp.equals(e)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public E top() throws StackEmptyException {
        if (size == 0) {
            throw new StackEmptyException();
        }
        return head.element;
    }

    @Override
    public void push(E e) {
        head = new Node(e, head);
        size++;
    }

    @Override
    public E pop() throws StackEmptyException {

        if (size == 0) {
            throw new StackEmptyException();
        }
        E temp = head.element;
        head = head.next;
        size--;
        return temp;
    }


    public boolean equals(Object o) {
        if (o == null || getClass() != o.getClass()) return false;
        LinkedStack<E> that = (LinkedStack<E>) o;
        if (that.size() != this.size()) return false;
        Node j = that.head;
        int counter = 0;
        for (Node i = head; counter < size; i = i.next, j = j.next) {
            if (i.element == null && j.element == null) {
                counter++;
                continue;
            }
            if ((i.element != null) && (j.element != null)) {
                if (!i.element.equals(j.element)) {
                    return false;
                }
            } else {
                return false;
            }
            counter++;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int resultat = 1;
        int counter = 0;
        for (Node i = head; counter < size; i = i.next) {
            if (i.element == null) {
                counter++;
                continue;
            }
            resultat = resultat * i.element.hashCode();
            counter++;
        }
        return resultat;
    }


    protected class Node {
        private final E element;
        private final Node next;

        protected Node(final E element, final Node next) {
            this.element = element;
            this.next = next;
        }
    }
}
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
matin_mhz
  • 1
  • 2
  • 2
    Your `contains` method empties out the entire stack in the process of checking whether the stack contains the element. That's... bad. – David Conrad Jun 13 '22 at 16:20

1 Answers1

3

I just realized you could in principle avoid explicitly casting to LinkedStack<E> and instead cast to LinkedStack<?>, since you check elements' equality separately down the line anyway.

As for the difference this makes - casting to LinkedStack<E> you assume that you're comparing this to a LinkedStack holding elements of the same type. The compiler can't check this assumption and warns about the unchecked cast. That could bring about a ClassCastException down the line if you handled the stack's elements as if they were of type E and they actually turned out to be some other type.
The wildcard generic <?> means you have no assumptions about the generic type of the particular LinkedStack you're working with, thus eliminating the warning.

That's what other answers to the "suppress unchecked cast warnings" mean when they say you'd best avoid unchecked casts unless absolutely necessary.

(I'm purposefully avoiding commenting on the rest of the provided code)

Yevgeniy
  • 141
  • 4
  • 1
    This is a good idea since it's `equals(Object)` anyway. To make it even smoother, OP could do the comparison with `Objects.equals(i.element, j.element)` and avoid the logic around whether the nodes contain a null element, using `java.util.Objects` (at the expense of commenting just a little on the rest of the provided code). – David Conrad Jun 13 '22 at 17:15