[英]Why does LinkedList not expose its Node class?
如果我從頭開始開發鏈表,我可以在我的業務實體 class 中存儲指向節點 object 的指針,並實現恆定的 O(1) remove和insertAfter操作。 在 java 標准庫實現中,它們是 O(n),在處理大型數據集時可能會有很大差異。
為什么他們不只是公開節點 class 並在其中封裝一些細節仍然使 class 本身(可能通過接口)可訪問? 這將使 LinkedList 更加靈活。
我們在 Apache Commons 或 Guava 中有類似FlexibleLinkedList的東西嗎?
ListIterator
為什么他們不只是公開節點 class 並在其中封裝一些細節仍然使 class 本身(可能通過接口)可訪問?
沒有必要。
為什么他們不只是公開節點 class 並在其中封裝一些細節仍然使 class 本身(可能通過接口)可訪問? 這將使 LinkedList 更加靈活。
那已經存在了。
如果您想獲得基於節點的操作的好處,例如:
您只需要使用ListIterator
()返回的 ListIterator 即可。 所有List
都提供此方法。
這個 class 封裝了在迭代中知道當前節點的邏輯,並提供了直接使用Node
的有效操作方法,例如:
add
- 將元素插入到next()
將返回的元素之前set
- 將next()
或previous()
返回的最后一個元素替換為指定元素remove
- 從列表中刪除next()
或previous()
返回的最后一個元素同時提供使用next()
和previous()
控制迭代的方法。
因此,您可以例如更改每隔一個元素:
LinkedList<Integer> values = new LinkedList<>(List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
int i = 0;
ListIterator<Integer> iter = values.listIterator();
while (iter.hasNext()) {
iter.next();
if (i % 2 == 0) {
iter.set(100);
}
i++;
}
導致
[100, 2, 100, 4, 100, 6, 100, 8, 100, 10]
而且這段代碼在O(n)
中運行,它不需要每次都重新定位節點。 與壞的等價物相反
for (int i = 0; i < list.size(); i++) {
if (i % 2 == 0) {
list.set(i, 100);
}
}
由於您所說的原因,它在O(n^2)
中運行。
Node
的好處一般來說,封裝和隱藏你的私人內部運作要好得多。 用戶不應打擾LinkedList
如何在幕后完成其工作。
此外,如果它會暴露Node
,用戶可以偷偷地編輯它們,整個列表就會變得瘋狂。
例如,用戶可以這樣做
Node a = list.getNodeAtIndex(3);
Node b = a.next;
Node c = b.next;
// Remove b
a.next = c;
c.previous = a;
無需調整列表的size
。 所以list.size()
現在會返回一個錯誤的數字,可能會導致迭代期間崩潰。
或者你也可以引入一個危險的循環:
a.next = b;
b.next = a;
或者忘記設置previous
,導致向后迭代時不同的列表:
a.next = c;
c.previous = b;
ListIterator
確保此類事情不會發生,同時提供相同的功能。 因此,它不是直接向用戶公開節點,而是僅公開所需的功能,以它可以完全控制的方法的形式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.