2014-01-18 52 views
6

我正在使用鏈表的java.util實現。我想知道爲什麼它允許我們添加空元素,我們甚至可以遍歷它們?爲什麼我們可以將null元素添加到java LinkedList中?

如果我們添加null元素並嘗試迭代它,那麼這不會破壞鏈表的點,我們有一個指向下一個元素的元素,而鏈表的常規實現會中斷。

+4

元素不指向任何東西。包含元素的節點指向下一個節點(可能還有前一個節點)。 –

回答

14

看看Java 7的源代碼,LinkedList被實現爲一系列節點。

private static class Node<E> { 
    E item; 
    Node<E> next; 
    Node<E> prev; 

    Node(Node<E> prev, E element, Node<E> next) { 
     this.item = element; 
     this.next = next; 
     this.prev = prev; 
    } 
} 

每個節點都有一個參考前面的節點和下一個節點,以及一個item。將空值插入列表中時,您插入的節點的item值爲null,但nextprev指針非空。

4

從概念上講,Java集合持有指向對象的指針而不是對象本身。當你看到List<String>認爲List<Pointer-to-String>。您可以將相同字符串地址的多個副本存儲在集合中。多個集合可以共享相同的對象指針,並且可以將空指針存儲在集合中。

您正在考慮將「指針」添加到結構本身的「常規」實現。 Java通過引入一個包含指向另一個指針的「標題」對象和一個指向你放入的對象的指針,從而將「鏈接」的細節與代碼分開。指向你的對象的指針可以爲null。在內部,LinkedList代碼在「標題」對象中使用空指針來指定列表的末尾。這個額外的指針稍慢一些,因爲你必須追趕它來獲得「有效載荷」。但它允許多態性(4段落)。

我們通常根本不會想到List實現的細節。我們編碼到「List」界面。 List允許我們插入和刪除指向對象的指針,並通過索引訪問這些指向對象的指針。指針可以爲空。

LinkedList快速插入/刪除,但隨機訪問速度較慢(它必須追逐「標頭」指針)。 ArrayList隨機訪問很快,但插入/移除速度慢(它必須複製內存)。您將代碼寫入「List」接口並根據您的使用選擇實現。而且您可以稍後更改實現,而無需更改使用List接口的代碼。

注意在C++標準模板庫中,std::list<std::string>自己創建一個對象集合(不是指向對象的指針),並且不能插入空值。類似Java的集合將是一個std::list<std::string *>,它是可以爲空的指針集合。

收集「指針」具有允許多態性的優點。如果我收集對象而不是指針,那麼我不能將一個SuperString放入字符串集合中,因爲代碼實際上是將結構複製到它自己的內存中。 SuperString對於一個String插槽來說太大了。但指針都是一樣的大小;我可以把一個指向SuperString的指針放入String指針集合中。

相關問題