- 介紹
首先來看ArrayList和LinkedList的集成類和接口的區別。
// lang java public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Queue<E>, Cloneable, Serializable
ArrayList實現了隨機訪問的接口,LinkedList實現了Quene的接口。
ArrayList是基於數據實現的list,而LinkedList是基於鏈表實現的list。所以,ArrayList擁有着數組的特性,LinkedList擁有着鏈表的特性。
- 優缺點
ArrayList
優點:適合隨機讀取的時候,讀取速度快,可以一步get(index)。
缺點:添加值很慢——一方面,添加數據在array中間的時候,需要移動后面的數;另一方面,當長度大於初始長度的時候,每添加一個數,都會需要擴容。
LinkedList:雙向鏈表
優點:添加值很快——添加在list中間也只需要更改指針;長度不固定。
實現棧和隊列方面,LinkedList要優於ArrayList。
- 其它
LinkedList的remove(int)和remove(Object)的方法的時間復雜度都是O(n),不是O(1).因為會有一個查找的過程。
LinkedList的remove(int)要優於remove(Object),因為remove(int)在查找的時候,會從鏈表的中間查找,如果int比中間小,找前半部分,否則找后半部分(類似二分查找)。
ArrayList的增刪比LinkedList的開銷更大,因為除了有查找的時間復雜度外,還有增刪的移動過程。
- 使用LinkedeList<Integer>實現對鏈表的排序(sougou筆試題)
//LinkedList<Integer>實現鏈表的排序 使用插入排序 public LinkedList<Integer> insertSortForLinkedList(LinkedList<Integer> list){ int len=list.size(); for(int i=1;i<len;i++){ int j=i-1; int temp=list.get(i); list.remove(i); //注意這里需要刪除元素 while(j>=0&&temp<list.get(j)){ j--; } list.add(j+1,temp); } return list; }
- 使用LinkedeList實現棧和隊列
Stack.java
import java.util.*; class Stack{ private LinkedList list; public Stack(){ list=new LinkedList(); } public Object top(){ //輸出最上面的元素 if(list.size()!=0){ return list.getFirst(); } return -1; } public void pop(){ //出棧 if(list.size()!=0){ list.removeFirst(); } } public void push(Object v){ //入棧 list.addFirst(v); } public int getLen(){ return list.size(); } }
Test.java
import java.util.*; class Test{ public static void main(String[] args){ Stack stack = new Stack(); stack.push("張三"); stack.push(3); stack.push("李四"); stack.push("5"); System.out.println("長度---"+stack.getLen()); //4 /** //注意這樣寫是有問題的,因為在出棧的過程中stack.getLen()是會發生變化的 for(int i=0;i<stack.getLen();i++){ System.out.println(stack.top()); stack.pop(); //System.out.println("長度---"+stack.getLen()); //4 } **/ /** //正確 int i=stack.getLen()-1; while(i>=0){ System.out.println(stack.top()); stack.pop(); i--; } **/ //正確,但是會引來不安全操作提醒 while(stack.getLen()>0){ System.out.println(stack.top()); stack.pop(); } System.out.println(stack.top()); stack.pop(); } }
為什么while的編譯時間長於for循環。