Java中List和ArrayList的區別


---恢復內容開始---

 轉載自:http://www.cnblogs.com/aisiteru/articles/1151874.html

       第一次看這篇文章時,是在CSDN博客中看到的,作者寫的初衷還是蠻好的,但是確實有錯誤的地方和不是很明

白的地方。於是就很想去看看原文,廢了半天的功夫終於找到了,原文還是一樣有出錯和我不理解的地方,我也把原

文的地址貼在上面了。三月份學習的Java集合框架這部分,這幾天拿出來整理就想再深入一點,因此也看了很多的關

於Java集合框架的文章,這篇我算是有一點點的體會,我只是改了一些我認為錯誤的地方和不通順的地方。

 

       改過的原文:

       List是一個接口,而ArrayList是List接口的一個實現類。 

       ArrayList類繼承並實現了List接口。 

       因此,List接口不能被構造,也就是我們說的不能創建實例對象,但是我們可以像下面那樣為List接口創建一個指

向自己的對象引用,而ArrayList實現類的實例對象就在這充當了這個指向List接口的對象引用。 

 

       個人見解:

       要是你已經學過了OOP,上面的部分是不難理解的,這是面向對象重要的知識點,面向對象最重要的就是多態,

我們都知道接口和抽象不能被實例化,但是它們可以創建一個指向自己的對象引用,它們的實現類或子類就在充當這

樣的角色,我想這就是面向對象編程中多態的優勢。前些日子在學習UML建模語言和Java設計模式的時候,深深地的

體會到了面向對象編程的好處,Java集合框架中用到也不足為奇,Java本身就是面向對象的編程語言。

       上面的理解可能有點難度,但是我們找一個具體的實例,就會理解起來比較容易。我們定義一個動物的抽象類

Animal,再定義一個繼承自Animal基類的Dog類,看下面的代碼就會理解抽象類和接口不能被實例化:

 

[java]  view plain  copy
 
  1. <span style="font-size:18px;">public class Test{  
  2.     public static void main(String[] args){  
  3.         Animal a1 = new Animal();//編譯出錯  
  4.         Animal a2 = new Dog();  
  5.     }  
  6. }  
  7.   
  8. abstract class Animal{  
  9.     //動物名字  
  10.     String name;  
  11.       
  12.     //動物叫聲  
  13.     public void shout(){  
  14.         System.out.println("叫聲...");  
  15.     }  
  16. }  
  17.   
  18. class Dog extends Animal{  
  19.     //狗類獨有的方法  
  20.     public void guard(){  
  21.         System.out.println("狗有看門的獨特本領!");  
  22.     }  
  23. }</span>  

        編譯結果:

 

 

       List list;//正確,list = null; 

       List list = new List();//是錯誤的用法

       List list = new ArrayList();這句創建了一個ArrayList實現類的對象后把它上溯到了List接口。此時它就是一個List對

象了,它有些ArrayList類具有的,但是List接口沒有的屬性和方法,它就不能再用了。 而ArrayList list=newArrayList();

創建一對象則保留了ArrayList的所有屬性和方法。 

 

       個人見解

       我們繼續上面的例子,如果我們創建的是抽象類的對象引用,那么這個對象只能調用自己的非抽象方法,下面的

是shout()方法,不能調用繼承它的子類的獨有的方法,在下面的就是guard()方法不能被a1調用,繼續測試代碼:

 

[java]  view plain  copy
 
  1. <span style="font-size:18px;">public class Test{  
  2.     public static void main(String[] args){  
  3.         Animal a1 = new Dog();  
  4.         a1.shout();//編譯通過  
  5.         //a1.guard();//編譯出錯  
  6.     }  
  7. }  
  8.   
  9. abstract class Animal{  
  10.     //動物名字  
  11.     String name;  
  12.       
  13.     //動物叫聲  
  14.     public void shout(){  
  15.         System.out.println("叫聲...");  
  16.     }  
  17. }  
  18.   
  19. class Dog extends Animal{  
  20.     //狗類獨有的方法  
  21.     public void guard(){  
  22.         System.out.println("狗有看門的獨特本領!");  
  23.     }  
  24. }  
  25. </span>  

 

       編譯結果:

       如果我們采用Dog d1 = new Dog();那么d1可以調用抽象類和子類的所有屬性和方法,這里不再測試。

 

       這是一個例子: 

 

[java]  view plain  copy
 
  1. <span style="font-size:18px;">import java.util.*;  
  2.   
  3. public class Demo{  
  4.     public static void main(String[] args){  
  5.         List list = new ArrayList();   
  6.                 ArrayList arrayList = new ArrayList();  
  7.                 list.trimToSize();//錯誤,沒有該方法。  
  8.                 arrayList.trimToSize();//ArrayList里有該方法。  
  9. }   
  10. }</span>  

 

       編譯一下就知道結果了。

 

       個人見解

       我剛在前面的文章里面把Java API中List接口和ArrayList實現類的方法都列出來了,可以看到List接口中並沒有

trimToSize()方法,但這個方法在它的實現類ArrayList中有。因此編譯的結果為:

 

 

        如果是下面這個樣子的: 

        List a=new ArrayList(); 

        則a擁有List的所有屬性和方法,不會擁有其實現類ArrayList的獨有的屬性和方法。 

        如果List與ArrayList中有相同的屬性(如int i),有相同的方法(如void f()), 

        則a.i是調用了List中的i 

        a.f()是調用了ArrayList中的f(); 

----------------------------------------------------------------------------------------------------------------

        問題的關鍵: 

        為什么要用 List list = new ArrayList() ,而不用 ArrayList alist = new ArrayList()呢? 

        問題就在於List接口有多個實現類,現在你用的是ArrayList,也許哪一天你需要換成其它的實現類,如 

LinkedList或者Vector等等,這時你只要改變這一行就行了: List list = new LinkedList(); 其它使用了list地方的代碼根

本不需要改動。 

       假設你開始用ArrayList alist = new ArrayList(), 這下你有的改了,特別是如果你使用了ArrayList實現類特有的方法

和屬性。

 

       個人見解

       上面的說明,我是在看了設計模式才恍然大悟的,設計模式的原則和理念果然是強大的,只有好好學習了面向對

象原則和設計模式,那么理解上面的就不再是難度,這樣的好處是為了代碼的可維護性,可復用性,可擴展性以及靈

活性,再者就是這符合了里氏代換原則和開閉原則。看來學習設計模式好處是大大的。

 

 

       地區用List arr = new ArrayList();定義;行業用ArrayList arr = new ArrayList();定義;則說明,行業里用到了ArrayList的

特殊的方法.

       另外的例子就是,在類的方法中,如下聲明:

        private void doMyAction(List list){}

        這樣這個方法能處理所有實現了List接口的類,一定程度上實現了泛型函數.

       如果開發的時候覺得ArrayList,HashMap的性能不能滿足你的需要,可以通過實現List,Map(或者Collection)來定制

你的自定義類.

 

        個人見解

        正因為List是接口,所以它的擴展性是良好的,這是面向對象編程最大的改變,也是它的核心,在這里我是體會

到了一句話,就是Java集合框架的學習最難體現你學習Java語言的程序都多深,看來我以前學習的程度只是停留在入

門級別了,這幾天可要好好再溫習重新認識一番Java集合框架了。

        可能理解不是很深,對於原文的理解也就這些了,不對的地方自己會及時更正。

---恢復內容結束---


免責聲明!

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



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