Java LinkedList源碼深入分析
1.LinkedList是基于鏈表的,而且是一個(gè)雙向鏈表,不需要連續(xù)內(nèi)存空間。
//可以看出Node是一個(gè)雙鏈表結(jié)構(gòu)
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;
}
}2.對于add操作,有兩種情況,
1)如果不指定位置,則在末尾添加。只需改變指針指向即可。
//尾插
void linkLast(E e) {
//保存的鏈表的尾部節(jié)點(diǎn)
final Node<E> l = last;
//新的節(jié)點(diǎn)的前一個(gè)node指向鏈表的最后一個(gè),next 為null
final Node<E> newNode = newNode < E > (l, e, null);
last = newNode;
if (l == null)//如果最后一個(gè)節(jié)點(diǎn)為null,說明鏈表是空的
first = newNode;
else//如果不為null,last的next節(jié)點(diǎn)指向新的節(jié)點(diǎn)
l.next = newNode;
size++;
modCount++;
}2)如果在指定位置添加,則需要遍歷鏈表。如果索引小于鏈表長度的一半,從頭遍歷,否則從尾部遍歷。調(diào)用node(index)進(jìn)行遍歷。
public void add(int index, E element) {
if (index == size)//新插入節(jié)點(diǎn)剛好在鏈表尾部
linkLast(element);
else
linkBefore(element, node(index));
}
Node<E> node(int index) {
//如果index小于鏈表的一半,則頭部遍歷
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else { //如果index大于鏈表的一半,則尾部遍歷
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
} void linkBefore(E e, Node<E> succ) {
// assert succ != null;
final Node<E> pred = succ.prev;
final Node<E> newNode = new Node<>(pred, e, succ);
succ.prev = newNode;
if (pred == null)
first = newNode;
else
pred.next = newNode;
size++;
modCount++;
}3.對于get和set方法都需要遍歷鏈表,相比ArrayList,效率要低。
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
public E set(int index, E element) {
checkElementIndex(index);
Node<E> x = node(index);
E oldVal = x.item;
x.item = element;
return oldVal;
}4.對于remove,則需要遍歷整個(gè)鏈表
public boolean remove(Object o) {
if (o == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null) {
unlink(x);
return true;
}
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item)) {
unlink(x);
return true;
}
}
}
return false;
}unlink 斷開鏈表中被刪節(jié)點(diǎn)前后的指向,建立新的指向。
E unlink(Node<E> x) {
// assert x != null;
final E element = x.item;
final Node<E> next = x.next;
final Node<E> prev = x.prev;
if (prev == null) {
first = next;
} else {
prev.next = next;
x.prev = null;
}
if (next == null) {
last = prev;
} else {
next.prev = prev;
x.next = null;
}
x.item = null;
size--;
modCount++;
return element;
}5.ArrayList分析
6.總結(jié):
1)對于get和set,Arraylist效率高,直接通過索引取值,而LinkedList,則需要遍歷鏈表。
2)對于Add方法,
如果添加到末尾,差不多。
如果插入在中間,ArrayList需要移動(dòng)素組,而LinkedList只需操作指針即可,效率要高。但是LinkedList,需要通過索引查找到要插入的位置。
3)對于remove方法。
如果刪除在尾部,差不多。
如果刪除中間某個(gè)元素,ArrayList則需要移動(dòng)數(shù)組。而Linkedlist如果刪除的是對象只需要操作指針即可,如果是按索引刪除,則需要遍歷,找到該元素。
到此這篇關(guān)于Java LinkedList源碼深入分析的文章就介紹到這了,更多相關(guān)Java LinkedList內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java httpclient請求form-data格式并設(shè)置boundary代碼實(shí)現(xiàn)方法
在 Java 開發(fā)中,經(jīng)常會(huì)遇到需要使用 httpclient 發(fā)送 form-data 格式請求的場景,本文將詳細(xì)介紹如何正確地實(shí)現(xiàn)這一操作,包括數(shù)據(jù)格式示例、常見報(bào)錯(cuò)及解決方法,本文通過實(shí)例代碼詳解講解,感興趣的朋友一起看看吧2025-01-01
java中rss解析器(rome.jar和jdom.jar)示例
這篇文章主要介紹了java中rss解析器(rome.jar和jdom.jar)示例,需要的朋友可以參考下2014-03-03
如何使用Java模擬退火算法優(yōu)化Hash函數(shù)
為了解決局部最優(yōu)解問題,1983年,Kirkpatrick等提出了模擬退火算法(SA)能有效的解決局部最優(yōu)解問題。模擬退火算法包含兩個(gè)部分即Metropolis算法和退火過程。Metropolis算法就是如何在局部最優(yōu)解的情況下讓其跳出來,是退火的基礎(chǔ)2021-06-06
Java應(yīng)用多機(jī)器部署解決大量定時(shí)任務(wù)問題
這篇文章主要介紹了Java應(yīng)用多機(jī)器部署解決大量定時(shí)任務(wù)問題,兩臺(tái)服務(wù)器同時(shí)部署了同一套代碼, 代碼中寫有spring自帶的定時(shí)任務(wù),但是每次執(zhí)行定時(shí)任務(wù)時(shí)只需要一臺(tái)機(jī)器去執(zhí)行,需要的朋友可以參考下2019-07-07
為什么說要慎用SpringBoot @ComponentScan
本文主要介紹了為什么說要慎用SpringBoot @ComponentScan,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-07-07
spring啟動(dòng)錯(cuò)誤Singleton bean creation not al
本文主要介紹了spring啟動(dòng)錯(cuò)誤Singleton bean creation not allowed while the singletons of this factory are indestruction,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
Springboot使用Logback實(shí)現(xiàn)日志配置與異常記錄
默認(rèn)情況下,SpringBoot內(nèi)部使用logback作為系統(tǒng)日志實(shí)現(xiàn)的框架,將日志輸出到控制臺(tái),不會(huì)寫到日志文件。本篇文章主要講解下如何自定義logabck.xml以及對logback文件中配置做一個(gè)詳解,需要的可以參考一下2022-11-11
MyBatis類型轉(zhuǎn)換模塊的實(shí)現(xiàn)
MyBatis是一個(gè)持久層框架ORM框架,實(shí)現(xiàn)數(shù)據(jù)庫中數(shù)據(jù)和Java對象中的屬性的雙向映射,那么不可避免的就會(huì)碰到類型轉(zhuǎn)換的問題,本文主要介紹了MyBatis類型轉(zhuǎn)換模塊的實(shí)現(xiàn),感興趣的可以了解一下2023-09-09

