zoukankan      html  css  js  c++  java
  • 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集合框架了。

            可能理解不是很深,对于原文的理解也就这些了,不对的地方自己会及时更正。

    ---恢复内容结束---

  • 相关阅读:
    关于lockkeyword
    关于多层for循环迭代的效率优化问题
    Android 面试精华题目总结
    Linux基础回想(1)——Linux系统概述
    linux源代码编译安装OpenCV
    校赛热身 Problem C. Sometimes Naive (状压dp)
    校赛热身 Problem C. Sometimes Naive (状压dp)
    校赛热身 Problem B. Matrix Fast Power
    校赛热身 Problem B. Matrix Fast Power
    集合的划分(递推)
  • 原文地址:https://www.cnblogs.com/zcscnn/p/7743507.html
Copyright © 2011-2022 走看看