java中ArrayList和LinkedList的區別


  • 介紹

  首先來看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循環。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM