wordpress用戶前端創(chuàng)建相冊(cè)關(guān)鍵詞seo公司推薦
一、ArrayList 和?Array 的區(qū)別
ArrayList
?內(nèi)部基于動(dòng)態(tài)數(shù)組實(shí)現(xiàn),比?Array
(靜態(tài)數(shù)組) 使用起來更加靈活:
ArrayList
?會(huì)根據(jù)實(shí)際存儲(chǔ)的元素動(dòng)態(tài)地?cái)U(kuò)容或縮容,而Array
被創(chuàng)建之后就不能改變它的長度了。ArrayList
允許你使用泛型來確保類型安全,Array
則不可以。ArrayList
中只能存儲(chǔ)對(duì)象。對(duì)于基本類型數(shù)據(jù),需要使用其對(duì)應(yīng)的包裝類(如 Integer、Double 等)。Array
可以直接存儲(chǔ)基本類型數(shù)據(jù),也可以存儲(chǔ)對(duì)象。ArrayList
支持插入、刪除、遍歷等常見操作,并且提供了豐富的 API 操作方法,比如add()
、remove()
等。Array
只是一個(gè)固定長度的數(shù)組,只能按照下標(biāo)訪問其中的元素,不具備動(dòng)態(tài)添加、刪除元素的能力。ArrayList
?創(chuàng)建時(shí)不需要指定大小,而?Array
?創(chuàng)建時(shí)必須指定大小。
以下是兩者之間的對(duì)比:
ArrayList:
// 初始化一個(gè) String 類型的 ArrayListArrayList<String> stringList = new ArrayList<>(Arrays.asList("hello", "world", "!"));// 添加元素到 ArrayList 中stringList.add("goodbye");System.out.println(stringList); // [hello, world, !, goodbye]// 修改 ArrayList 中的元素stringList.set(0, "hi");System.out.println(stringList); // [hi, world, !, goodbye]// 刪除 ArrayList 中的元素stringList.remove(0);System.out.println(stringList); // [world, !, goodbye]
Array:?
// 初始化一個(gè) String 類型的數(shù)組String[] stringArr = new String[]{"hello", "world", "!"};// 修改數(shù)組元素的值stringArr[0] = "goodbye";System.out.println(Arrays.toString(stringArr)); // [goodbye, world, !]// 刪除數(shù)組中的元素,需要手動(dòng)移動(dòng)后面的元素for (int i = 0; i < stringArr.length - 1; i++) {stringArr[i] = stringArr[i + 1];}stringArr[stringArr.length - 1] = null;System.out.println(Arrays.toString(stringArr)); // [world, !, null]
二、ArrayList 和?LinkedList?的區(qū)別
從以下幾個(gè)方面來比較:
- 線程安全方面:
ArrayList
和LinkedList
都是不同步的,也就是非線程安全; - 底層數(shù)據(jù)結(jié)構(gòu)方面:
ArrayList
底層使用的是Object
數(shù)組;LinkedList
底層使用的是 雙向鏈表 數(shù)據(jù)結(jié)構(gòu)(JDK1.6 之前為循環(huán)鏈表,JDK1.7 取消了循環(huán)。注意雙向鏈表和雙向循環(huán)鏈表的區(qū)別,下面有介紹到!) - 插入和刪除是否受元素位置的影響:
ArrayList
采用數(shù)組存儲(chǔ),所以插入和刪除元素的時(shí)間復(fù)雜度受元素位置的影響。 比如:執(zhí)行add(E e)
方法的時(shí)候,ArrayList
會(huì)默認(rèn)在將指定的元素追加到此列表的末尾,這種情況時(shí)間復(fù)雜度就是 O(1)。但是如果要在指定位置 i 插入和刪除元素的話(add(int index, E element)
),時(shí)間復(fù)雜度就為 O(n)。因?yàn)樵谶M(jìn)行上述操作的時(shí)候集合中第 i 和第 i 個(gè)元素之后的(n-i)個(gè)元素都要執(zhí)行向后位/向前移一位的操作。LinkedList
采用鏈表存儲(chǔ),所以在頭尾插入或者刪除元素不受元素位置的影響(add(E e)
、addFirst(E e)
、addLast(E e)
、removeFirst()
、removeLast()
),時(shí)間復(fù)雜度為 O(1),如果是要在指定位置i
插入和刪除元素的話(add(int index, E element)
,remove(Object o)
,remove(int index)
), 時(shí)間復(fù)雜度為 O(n) ,因?yàn)樾枰纫苿?dòng)到指定位置再插入和刪除。
- 是否支持快速隨機(jī)訪問:
LinkedList
不支持高效的隨機(jī)元素訪問,而ArrayList
(實(shí)現(xiàn)了RandomAccess
接口) 支持??焖匐S機(jī)訪問就是通過元素的序號(hào)快速獲取元素對(duì)象(對(duì)應(yīng)于get(int index)
方法)。 - 內(nèi)存空間占用:
ArrayList
的空間浪費(fèi)主要體現(xiàn)在在 list 列表的結(jié)尾會(huì)預(yù)留一定的容量空間,而 LinkedList 的空間花費(fèi)則體現(xiàn)在它的每一個(gè)元素都需要消耗比 ArrayList 更多的空間(因?yàn)橐娣胖苯雍罄^和直接前驅(qū)以及數(shù)據(jù))。
我們?cè)陧?xiàng)目中一般是不會(huì)使用到?LinkedList
?的,需要用到?LinkedList
?的場景幾乎都可以使用?ArrayList
?來代替,并且,性能通常會(huì)更好!?
補(bǔ)充:雙向鏈表 和 雙向循環(huán)鏈表
雙向鏈表:?包含兩個(gè)指針,一個(gè) prev 指向前一個(gè)節(jié)點(diǎn),一個(gè) next 指向后一個(gè)節(jié)點(diǎn)。
雙向循環(huán)鏈表:?最后一個(gè)節(jié)點(diǎn)的 next 指向 head,而 head 的 prev 指向最后一個(gè)節(jié)點(diǎn),構(gòu)成一個(gè)環(huán)。
三、ArrayList 和?Vector??的區(qū)別
ArrayList
是List
的主要實(shí)現(xiàn)類,底層使用Object[]
存儲(chǔ),適用于頻繁的查找工作,線程不安全 。Vector
是List
的古老實(shí)現(xiàn)類,底層使用Object[]
存儲(chǔ),線程安全。- ArrayList 在內(nèi)存不夠時(shí)默認(rèn)是擴(kuò)展 50% + 1 個(gè), Vector 是默認(rèn)擴(kuò)展 1 倍。