首先我必须声明我所说的pop()和poll()函数都是类LinkedList中的,我并不确定是不是有相同的函数出现在别的类中,对于别的类的情况我也不敢妄下结论。
这个是我在学习LinkedList类的时候发现的,我发现pop()和poll()竟然都输出了头结点元素,难道两个函数功能一致,那为什么要搞两个不一样的函数?
直接上源码:
在开始之前先明确LinkedList的内部成员
transient int size = 0;//记录链表长度
/**
* Pointer to first node.
* Invariant: (first == null && last == null) ||
* (first.prev == null && first.item != null)
*/
transient Node<E> first;//头结点指针
/**
* Pointer to last node.
* Invariant: (first == null && last == null) ||
* (last.next == null && last.item != null)
*/
transient Node<E> last;//尾节点指针(这里的节点是双向节点)
这里的节点是双向节点)
本问题的核心函数 unlinkedFirst,这个函数是LinkedList内的一个函数,一会会发现pop()和poll()都用到了这个函数
/**
* Unlinks non-null first node f.
*/
private E unlinkFirst(Node<E> f) {
// assert f == first && f != null;这个函数使用的要求是f必须是第一个节点并且f不是null,所以这个函数也只是作为一个内部函数
final E element = f.item; //首先要获取到f节点的内容
final Node<E> next = f.next;//把未来头结点的指针暂存为next
f.item = null;//现在开始清除原头结点
f.next = null; // help GC 使原头结点成为没有指针指向的孤立节点,到时jvm会把他回收掉
first = next;//与新的头结点建立连接,原来的第二节点成为现在的头结点
if (next == null)//如果现在的节点为空
last = null;//那么尾节点也设为空
else
next.prev = null;//否则新头结点的前向指针设为空(这里面的节点都是双向节点)
size--;
modCount++;//这个参数记录的是列表在结构上被修改的次数
return element;
}
总结一下,这个函数的使用要求的是输入非空头结点引用,这个函数的作用是删除头结点,并建立新的头。
现在再比较下pop()和poll()的源码:
/**
* Retrieves and removes the head (first element) of this list.返回并且删除头节点
*
* @return the head of this list, or {@code null} if this list is empty
* @since 1.5
*/
public E poll() {
final Node<E> f = first;//先取得头结点的引用
return (f == null) ? null : unlinkFirst(f);//确保头结点不为null 然后直接调用上面的函数
}
/**
* Pops an element from the stack represented by this list. In other
* words, removes and returns the first element of this list.从该列表代表的堆栈中弹出一个元素,换句话讲,删除并返回该列表的第一个元素
* <p>This method is equivalent to {@link #removeFirst()}.
*
* @return the element at the front of this list (which is the top
* of the stack represented by this list)
* @throws NoSuchElementException if this list is empty
* @since 1.6
*/
public E pop() {
return removeFirst();
}
public E removeFirst() {
final Node<E> f = first;//先取得头结点的引用
if (f == null)
throw new NoSuchElementException();
return unlinkFirst(f);//确保头结点不为null,然后直接调用之前讲的函数
}
//确保头结点不为null,然后直接调用之前讲的函数
}
结论:可以发现这两个函数的代码实现是基本一致的,如果一定要说区别那么就是当头结点为空的时候,两个函数的处理方式不同:poll()选择返回null,pop()选择抛出异常。
也可以说,两个函数虽然实现效果一样,但他们字面意义不同。
如有不妥,望指正,谢谢!