Queue implementation in Java
Bug

dequeue doesn't set last to null when the queue becomes empty. On the other hand, isEmpty relies on last being null.
enqueue should be streamlined to

    if (first == null) {
        first = p;
    } else {
        last-&gt;next = p;
    }
    last = p;
    size++;


to clearly state common vs different actions.