1. 程式人生 > >Java中List和ArrayList的區別(加入了個人見解)

Java中List和ArrayList的區別(加入了個人見解)

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

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

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

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

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

       改過的原文:

       List是一個介面,而ArrayList是List介面的一個實現類。 

       ArrayList類是繼承AbstractList抽象類和實現List介面的一個實現類。 

       因此,List介面不能被構造,也就是我們說的不能建立例項物件,但是我們可以像下面那樣為List介面建立一個指

向自己的物件引用,而ArrayList實現類的例項物件就在這充當了這個指向List介面的物件引用。 

       個人見解:

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

我們都知道介面和抽象類都不能被例項化,但是它們可以建立一個指向自己的物件引用,它們的實現類或子類就在充當這

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

體會到了面向物件程式設計的好處,Java集合框架中用到也不足為奇,Java本身就是面向物件的程式語言。

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

Animal,再定義一個繼承自Animal基類的Dog類,看下面的程式碼就會理解抽象類和介面不能被例項化:

<span style="font-size:18px;">public class Test{
	public static void main(String[] args){
		Animal a1 = new Animal();//編譯出錯
		Animal a2 = new Dog();
	}
}

abstract class Animal{
	//動物名字
	String name;
	
	//動物叫聲
	public void shout(){
		System.out.println("叫聲...");
	}
}

class Dog extends Animal{
	//狗類獨有的方法
	public void guard(){
		System.out.println("狗有看門的獨特本領!");
	}
}</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呼叫,繼續測試程式碼

<span style="font-size:18px;">public class Test{
	public static void main(String[] args){
		Animal a1 = new Dog();
		a1.shout();//編譯通過
		//a1.guard();//編譯出錯
	}
}

abstract class Animal{
	//動物名字
	String name;
	
	//動物叫聲
	public void shout(){
		System.out.println("叫聲...");
	}
}

class Dog extends Animal{
	//狗類獨有的方法
	public void guard(){
		System.out.println("狗有看門的獨特本領!");
	}
}
</span>

       編譯結果:


       如果我們採用Dog d1 = new Dog();那麼d1可以呼叫抽象類和子類的所有屬性和方法,這裡不再測試。

       這是一個例子: 

<span style="font-size:18px;">import java.util.*;

public class Demo{
	public static void main(String[] args){
		List list = new ArrayList(); 
                ArrayList arrayList = new ArrayList();
                list.trimToSize();//錯誤,沒有該方法。
                arrayList.trimToSize();//ArrayList裡有該方法。
} 
}</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集合框架了。

        可能理解不是很深,對於原文的理解也就這些了,不對的地方自己會及時更正。本來想畫圖說明的,但是由於自

己UML學習的不怎樣,就沒有去認真的畫,以後還是多多學習畫圖的。