Java中的Arrays、ArrayList、Vector、Collections区别

来源:互联网 发布:淘宝运营月度工作总结 编辑:程序博客网 时间:2024/06/07 07:23

一、Arrays

API中的解释http://docs.oracle.com/javase/1.5.0/docs/api

简单学 http://hi.baidu.com/chen_767/item/8195fcab4551f2f415329bf4

http://blog.sina.com.cn/s/blog_8c53d73f0100y74d.html


数组是一个动态的,也就是说,它的大小可以根据输入来测定。例如:

Scanner s=new Scanner(System.in);int n=s.nextInt();int[] array=new int[n];

输出数组的方式:

1、循环输出

2、作为集合输出:System.out.println(Arrays.asList(数组));

注意:对于int[]数组不能直接这样做,因为asList()方法的参数必须是对象。应该先把int[]转化为Integer[]。对于其他primitive类型的数组也是如此,必须先转换成相应的wrapper类型数组。

int[] a={1,2,3,4};Integer[] integer=new Integer[a.length];for(int i=0;i<a.length-1;i++){Integer ing=a[i];integer[i]=ing;}

3、toString()方法:System.out.println(Arrays.toString(数组));

同样,这个方法也需要上面2、的转换,才可以用这个方法正确输出。


快速复制数组:

1、使用循环结构 这种方法最灵活。唯一不足的地方可能就是代码较多 

2、 使用Object类的clone() 方法, 这种方法最简单,得到原数组的一个副本。灵活形也最差。效率最差,尤其是在数组元素很大或者复制对象数组时。

3 、使用Systems的arraycopy 这种方法被告之速度最快,并且灵活性也较好,可以指定原数组名称、以及元素的开始位置、复制的元素的个数,目标数组名称、目标数组的位置。

System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length);

4、Arrarys类的copyOf()方法与copyOfRange()方法可实现对数组的复制。


二、ArrayList

API中的解释 http://docs.oracle.com/javase/1.5.0/docs/api/

ArrayList详解 http://blog.csdn.net/tianmo2010/article/details/7046602

与Arrays的比较 http://hi.baidu.com/zhangrg_123/item/17aa446d334bd80ba0cf0f41

http://www.cnblogs.com/ITEagle/archive/2010/02/04/1663719.html

ArrayList是Array的复杂版本,通过add()和get()方法来增加和获取元素,比Array少了[]而已。

ArrayList实现了可变大小的数组。它允许所有元素,包括null。ArrayList没有同步。 size,isEmpty,get,set方法运行时间为常数。但是add方法开销为分摊的常数,添加n个元素需要O(n)的时间。其他的方法运行时间为线性。 每个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组的大小。这个容量可随着不断添加新元素而自动增加,但是增长算法 并没有定义。当需要插入大量元素时,在插入前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率。 和LinkedList一样,ArrayList也是非同步的(unsynchronized)。

下面是ensureCapacity()方法的使用效率

import java.util.*;public class Practice {public static void main(String[] args){final int N = 1000000;Object obj = new Object();//没用调用ensureCapacity()方法初始化ArrayList对象ArrayList list = new ArrayList();long startTime = System.currentTimeMillis();for(int i=0;i<=N;i++){list.add(obj);}long endTime = System.currentTimeMillis();System.out.println("没有调用ensureCapacity()方法所用时间:" + (endTime - startTime) + "ms");//调用ensureCapacity()方法初始化ArrayList对象list = new ArrayList();startTime = System.currentTimeMillis();list.ensureCapacity(N);//预先设置list的大小for(int i=0;i<=N;i++){list.add(obj);}endTime = System.currentTimeMillis();System.out.println("调用ensureCapacity()方法所用时间:" + (endTime - startTime) + "ms");//初始化容量list = new ArrayList(N);startTime = System.currentTimeMillis();for(int i=0;i<=N;i++){list.add(obj);}endTime = System.currentTimeMillis();System.out.println("调用ensureCapacity()方法所用时间:" + (endTime - startTime) + "ms");}}
运行结果:

没有调用ensureCapacity()方法所用时间:28ms
调用ensureCapacity()方法所用时间:24ms
使用初始化容量的方法所用时间:21ms

【引用】


1.   如果你不能确定ensureCapacity()方法到底是干嘛用的,最好不要随便用它。 

2.   指定位置来往ArrayList中插入元素有可能引用元素的大量移动,是极其影响效率的,也不要滥用。 

      任何一个ArrayList对象都有一个capacity属性,用来指示该ArrayList的最小容量,用“容量”这个词容易引起像本贴楼主那样的误解,我觉得用“容纳能力”比较贴切。
 

      我们知道ArrayList的内部是采用数组来存储元素的,由于java数组都是定长的,所以这个数组的大小一定是固定的,这个大小就是capacity。我们可以肯定capacity一定是大于或等于ArrayList的size,那么当size不断增加到了要超过capacity的时候,ArrayList就不得不重新创建新的capacity来容纳更多的元素,这时需要首先建立一个更长的数组,将原来的数组中的元素复制到新数组中,再删除原来的数组。可见当ArrayList越来越大时,这种操作的消耗也是越来越大的。 

      为了减少这种不必要的重建capacity的操作,当我们能肯定ArrayList大致有多大(或者至少会有多大)时,我们可以先让ArrayList把capacity设为我们期望的大小,以避免多余的数组重建。 

      假设ArrayList自动把capacity设为10,每次重建时将长度递增原来的三分之二,那么当我们需要大约存储50个元素到ArrayList中时,就会大约需要重建数组4次,分别是在增加第11、第17、第26、第39个元素的时候进行的。如果我们一开始就让ArrayList的capacity为50,那么不需要任何数组重建就能完成所有插入操作了。 

       java允许我们在构造ArrayList的同时指定capacity,如new   ArrayList(50),也允许在以后将它设得更大,而增大capacity就是使用ensureCapacity()方法。注意:capacity只能比原来的更大,而不能比原来的更小,否则java会忽略该操作。ArrayList的初始默认capacity为10,所以给capacity指定小于10的整数是毫无意义的。 

       最后说说ArrayList的size,前面说过,size一定小于等于capactiy,而且更重要的是,访问超过size的位置将抛出异常,尽管这个位置可能没有超过capacity。ensureCapacity()只可能增加capacity,而不会对size有任何影响。要增加size,只能用add()方法。

二、Vector

API中的解释 http://www.blogjava.net/Yang/archive/2006/01/05/26662.html

三、Collections

API中的解释 http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html

基础学习Collections   http://sunboyyyl.blog.163.com/blog/static/224738120121741039291/

关于Java Collections API不知道的5件事(第一部分)(深入学习) http://www.ibm.com/developerworks/cn/java/j-5things2.html

关于Java Collections API不知道的5件事(第二部分)(深入学习)http://www.ibm.com/developerworks/cn/java/j-5things3.html

 如何遍历Collection中的每一个元素?
   1、不论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个迭代子,使用该迭代子即可逐一访问Collection中每一个元素。典型的用法如下:  

Iterator it = collection.iterator(); // 获得一个迭代子 while(it.hasNext()) {  Object obj = it.next(); // 得到下一个元素  }

          2、或者直接输出:

        System.out.println(Collection  collection);

          3、容器类默认没有考虑线程安全问题,必须自行实现同步,如:

synchronized(arraylist){  arraylist.add(new someclass());}

事实上,可以返回一个同步化的容器对象,使用java.util.Collections的synchronizedXXX()方法,如:

List list=Collections.synchronizedList(new ArrayList());


虽然返回的对象是同步化的,在存取数据时会进行同步化的工作,但使用Iterator遍历对象时,list使用Iterator()方法返回的Iterator对象并没有保证线程的安全,所以遍历时仍必须实现同步化,如:


List list=Collections.synchronizedList(new ArrayList());synchronized(list){ Iterator i=list.iterator();while(i.hasNext())System.out.println(i.next());}



	
				
		
原创粉丝点击