日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

LinkedList插入元素一定比ArrayList快吗

發布時間:2025/3/20 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LinkedList插入元素一定比ArrayList快吗 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在選擇數據結構的時候,我們通常會考慮每種數據結構不同操作的時間復雜度,以及使用場景兩個因素。

對于數組,隨機元素訪問的時間復雜度是 O(1),元素插入操作是 O(n);

對于鏈表,隨機元素訪問的時間復雜度是 O(n),元素插入操作是 O(1)。

那么,在大量的元素插入、很少的隨機訪問的業務場景下,是不是就應該使用 LinkedList 呢?接下來,我們寫一段代碼測試下兩者隨機訪問和插入的性能吧。

我們定義下面幾個方法,分別為隨機訪問LinkedList數組和ArrayList數組,往LinkedList和ArrayList中隨機插入元素。

? ?private static void linkedListGet(int elementCount, int loopCount) {List<Integer> list = IntStream.rangeClosed(1, elementCount).boxed().collect(Collectors.toCollection(LinkedList::new));IntStream.rangeClosed(1, loopCount).forEach(i -> list.get(ThreadLocalRandom.current().nextInt(elementCount)));} ?private static void arrayListGet(int elementCount, int loopCount) {List<Integer> list = IntStream.rangeClosed(1, elementCount).boxed().collect(Collectors.toCollection(ArrayList::new));IntStream.rangeClosed(1, loopCount).forEach(i -> list.get(ThreadLocalRandom.current().nextInt(elementCount)));} ?private static void linkedListAdd(int elementCount, int loopCount) {List<Integer> list = IntStream.rangeClosed(1, elementCount).boxed().collect(Collectors.toCollection(LinkedList::new));IntStream.rangeClosed(1, loopCount).forEach(i -> list.add(ThreadLocalRandom.current().nextInt(elementCount), 1));} ?private static void arrayListAdd(int elementCount, int loopCount) {List<Integer> list = IntStream.rangeClosed(1, elementCount).boxed().collect(Collectors.toCollection(ArrayList::new));IntStream.rangeClosed(1, loopCount).forEach(i -> list.add(ThreadLocalRandom.current().nextInt(elementCount), 1));}

測試一下:

我們定義一個10萬元素的數組,然后測試訪問時間和插入時間,結果如下:

StopWatch '': running time = 4827155600 ns --------------------------------------------- ns ? ? ? ? % ? ? Task name --------------------------------------------- 4808820500 100% linkedListGet 018335100 000% arrayListGet ? StopWatch '': running time = 28181287000 ns --------------------------------------------- ns ? ? ? ? % ? ? Task name --------------------------------------------- 27238759200 097% linkedListAdd 942527800 003% arrayListAdd

可以很明顯的看到ArrayList無論是隨機訪問,還是隨機插入,所需的時間都遙遙領先于LinkedList。

翻看 LinkedList 源碼發現,插入操作的時間復雜度是 O(1) 的前提是,你已經有了那個要插入節點的指針。但,在實現的時候,我們需要先通過循環獲取到那個節點的 Node,然后再執行插入操作。前者也是有開銷的,不可能只考慮插入操作本身的代價:

? public void add(int index, E element) {checkPositionIndex(index); ?if (index == size)linkLast(element);elselinkBefore(element, node(index)); } ? Node<E> node(int index) {// assert isElementIndex(index); ?if (index < (size >> 1)) {Node<E> x = first;for (int i = 0; i < index; i++)x = x.next;return x;} else {Node<E> x = last;for (int i = size - 1; i > index; i--)x = x.prev;return x;} }

所以,對于插入操作,LinkedList 的時間復雜度其實也是 O(n)。繼續做更多實驗的話你會發現,在各種常用場景下,LinkedList 幾乎都不能在性能上勝出 ArrayList。

?

我們繼續測試一下在尾部插入元素:

? ?private static void linkedListAddLast(int elementCount, int loopCount) {List<Integer> list = IntStream.rangeClosed(1, elementCount).boxed().collect(Collectors.toCollection(LinkedList::new));IntStream.rangeClosed(1, loopCount).forEach(i -> list.add(ThreadLocalRandom.current().nextInt(elementCount)));} ?private static void arrayListAddLast(int elementCount, int loopCount) {List<Integer> list = IntStream.rangeClosed(1, elementCount).boxed().collect(Collectors.toCollection(ArrayList::new));IntStream.rangeClosed(1, loopCount).forEach(i -> list.add(ThreadLocalRandom.current().nextInt(elementCount)));}

測試參數還是同上,測試結果如下:

StopWatch '': running time = 95097500 ns --------------------------------------------- ns ? ? ? ? % ? ? Task name --------------------------------------------- 078869800 083% linkedListAddLast 016227700 017% arrayListAddLast

我們繼續測試一下在頭部插入元素:

? ?private static void linkedListAddFirst(int elementCount, int loopCount) {LinkedList<Integer> list = IntStream.rangeClosed(1, elementCount).boxed().collect(Collectors.toCollection(LinkedList::new));IntStream.rangeClosed(1, loopCount).forEach(i -> list.addFirst(ThreadLocalRandom.current().nextInt(elementCount)));} ?private static void arrayListAddFirst(int elementCount, int loopCount) {List<Integer> list = IntStream.rangeClosed(1, elementCount).boxed().collect(Collectors.toCollection(ArrayList::new));IntStream.rangeClosed(1, loopCount).forEach(i -> list.add(0, ThreadLocalRandom.current().nextInt(elementCount)));}

這次的測試結果如下:

StopWatch '': running time = 1832579700 ns --------------------------------------------- ns ? ? ? ? % ? ? Task name --------------------------------------------- 087754700 005% linkedListAddFirst 1744825000 095% arrayListAddFirst

總結:

ArrayList在大部分時候的性能都明顯要強于LinkedList。即使是對于增刪少查詢多這一場景。LinkedList只有在頭部插入元素的時候,性能會明顯優于ArrayList。

LinkedList并沒有想象中的那么好用,使用需謹慎。

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的LinkedList插入元素一定比ArrayList快吗的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。