Arraylist解析

一.ArrayList概述

  • ArrayList 是一个数组队列,相当于动态数组。与Java中的数组相比,它的容量能动态增长。它继承于AbstractList,实现了List,RandomAccess[随机访问],Cloneable[可克隆], java.io.Serializable[序列化]这些接口。
  • ArrayList 继承了AbstractList,实现了List。它是一个数组队列,提供了相关的添加、删除、修改、遍历等功能。
  • ArrayList 实现了RandmoAccess接口,即提供了随机访问功能。RandmoAccess是java中用来被List实现,为List提供快速访问功能的。在ArrayList中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。稍后,我们会比较List的“快速随机访问”和“通过Iterator迭代器访问”的效率。
  • ArrayList 实现了Cloneable接口,即覆盖了函数clone(),能被克隆
  • ArrayList 实现java.io.Serializable接口,这意味着ArrayList支持序列化,能通过序列化去传输。
  • 和Vector不同,ArrayList中的操作不是线程安全的。所以,建议在单线程中才使用ArrayList,而在多线程中可以选择Vector或者CopyOnWriteArrayList。
PS:以上继承关系可以表示为以下形式:

二.ArrayList之API  


1.ArrayList和Collection之间的关系

*实线代表直接继承的父类,虚线代表实现的接口;

2.ArrayList类的API

[java]  view plain  copy
  1. <span style="font-family:Microsoft YaHei;">// Collection中定义的API  
  2. boolean             add(E object)//添加一个数组对象  
  3. boolean             addAll(Collection<? extends E> collection)//添加一个包含Collection的对象  
  4. void              clear()//清空  
  5. boolean             contains(Object object)//包含  
  6. boolean             containsAll(Collection<?> collection)  
  7. boolean             equals(Object object)//判等  
  8. int               hashCode()  
  9. boolean             isEmpty()//判空  
  10. Iterator<E>             iterator()  
  11. boolean             remove(Object object)//删除  
  12. boolean             removeAll(Collection<?> collection)  
  13. boolean             retainAll(Collection<?> collection)  
  14. int               size()  
  15. <T> T[]             toArray(T[] array)  
  16. Object[]             toArray()  
  17. // AbstractCollection中定义的API  
  18. void              add(int location, E object)  
  19. boolean             addAll(int location, Collection<? extends E> collection)  
  20. E                get(int location)//获取某个元素值  
  21. int               indexOf(Object object)  
  22. int               lastIndexOf(Object object)  
  23. ListIterator<E>             listIterator(int location)  
  24. ListIterator<E>             listIterator()  
  25. E                remove(int location)  
  26. E                set(int location, E object)  
  27. List<E>             subList(int start, int end)  
  28. // ArrayList新增的API  
  29. Object             clone()//  
  30. void              ensureCapacity(int minimumCapacity)//保证容量不小于元素个数  
  31. void              trimToSize()  
  32. void              removeRange(int fromIndex, int toIndex)  
  33. </span>  

3.ArrayList的源码解析

[java]  view plain  copy
  1. <span style="font-family:Microsoft YaHei;">package java.util;  
  2. public class ArrayList<E> extends AbstractList<E>  
  3.         implements List<E>, RandomAccess, Cloneable, java.io.Serializable  
  4. {  
  5.     // 序列版本号  
  6.     private static final long serialVersionUID = 8683452581122892189L;  
  7.     // 保存ArrayList中数据的数组  
  8.     private transient Object[] elementData;  
  9.     // ArrayList中实际数据的数量  
  10.     private int size;  
  11.     // ArrayList带容量大小的构造函数。  
  12.     public ArrayList(int initialCapacity) {  
  13.         super();  
  14.         if (initialCapacity < 0)  
  15.             throw new IllegalArgumentException("Illegal Capacity: "+  
  16.                                                initialCapacity);  
  17.         // 新建一个数组  
  18.         this.elementData = new Object[initialCapacity];  
  19.     }  
  20.     // ArrayList构造函数。默认容量是10。  
  21.     public ArrayList() {  
  22.         this(10);  
  23.     }  
  24.     // 创建一个包含collection的ArrayList  
  25.     public ArrayList(Collection<? extends E> c) {  
  26.         elementData = c.toArray();  
  27.         size = elementData.length;  
  28.         // c.toArray might (incorrectly) not return Object[] (see 6260652)  
  29.         if (elementData.getClass() != Object[].class)  
  30.             elementData = Arrays.copyOf(elementData, size, Object[].class);  
  31.     }  
  32.     // 将当前容量值设为 =实际元素个数  
  33.     public void trimToSize() {  
  34.         modCount++;  
  35.         int oldCapacity = elementData.length;  
  36.         if (size < oldCapacity) {  
  37.             elementData = Arrays.copyOf(elementData, size);  
  38.         }  
  39.     }  
  40.     // 确定ArrarList的容量。  
  41.     // 若ArrayList的容量不足以容纳当前的全部元素,设置 新的容量=“(原始容量x3)/2 + 1”  
  42.     public void ensureCapacity(int minCapacity) {  
  43.         // 将“修改统计数”+1  
  44.         modCount++;  
  45.         int oldCapacity = elementData.length;  
  46.         // 若当前容量不足以容纳当前的元素个数,设置 新的容量=“(原始容量x3)/2 + 1”  
  47.         if (minCapacity > oldCapacity) {  
  48.             Object oldData[] = elementData;  
  49.             int newCapacity = (oldCapacity * 3)/2 + 1;  
  50.             if (newCapacity < minCapacity)  
  51.                 newCapacity = minCapacity;  
  52.             elementData = Arrays.copyOf(elementData, newCapacity);  
  53.         }  
  54.     }  
  55.     // 添加元素e  
  56.     public boolean add(E e) {  
  57.         // 确定ArrayList的容量大小  
  58.         ensureCapacity(size + 1);  // Increments modCount!!  
  59.         // 添加e到ArrayList中  
  60.         elementData[size++] = e;  
  61.         return true;  
  62.     }  
  63.     // 返回ArrayList的实际大小  
  64.     public int size() {  
  65.         return size;  
  66.     }  
  67.     // 返回ArrayList是否包含Object(o)  
  68.     public boolean contains(Object o) {  
  69.         return indexOf(o) >= 0;  
  70.     }  
  71.     // 返回ArrayList是否为空  
  72.     public boolean isEmpty() {  
  73.         return size == 0;  
  74.     }  
  75.     // 正向查找,返回元素的索引值  
  76.     public int indexOf(Object o) {  
  77.         if (o == null) {  
  78.             for (int i = 0; i < size; i++)  
  79.             if (elementData[i]==null)  
  80.                 return i;  
  81.             } else {  
  82.                 for (int i = 0; i < size; i++)  
  83.                 if (o.equals(elementData[i]))  
  84.                     return i;  
  85.             }  
  86.             return -1;  
  87.         }  
  88.         // 反向查找,返回元素的索引值  
  89.         public int lastIndexOf(Object o) {  
  90.         if (o == null) {  
  91.             for (int i = size-1; i >= 0; i--)  
  92.             if (elementData[i]==null)  
  93.                 return i;  
  94.         } else {  
  95.             for (int i = size-1; i >= 0; i--)  
  96.             if (o.equals(elementData[i]))  
  97.                 return i;  
  98.         }  
  99.         return -1;  
  100.     }  
  101.     // 反向查找(从数组末尾向开始查找),返回元素(o)的索引值  
  102.     public int lastIndexOf(Object o) {  
  103.         if (o == null) {  
  104.             for (int i = size-1; i >= 0; i--)  
  105.             if (elementData[i]==null)  
  106.                 return i;  
  107.         } else {  
  108.             for (int i = size-1; i >= 0; i--)  
  109.             if (o.equals(elementData[i]))  
  110.                 return i;  
  111.         }  
  112.         return -1;  
  113.     }  
  114.   
  115.     // 返回ArrayList的Object数组  
  116.     public Object[] toArray() {  
  117.         return Arrays.copyOf(elementData, size);  
  118.     }  
  119.     // 返回ArrayList的模板数组。所谓模板数组,即可以将T设为任意的数据类型  
  120.     public <T> T[] toArray(T[] a) {  
  121.         // 若数组a的大小 < ArrayList的元素个数;  
  122.         // 则新建一个T[]数组,数组大小是“ArrayList的元素个数”,并将“ArrayList”全部拷贝到新数组中  
  123.         if (a.length < size)  
  124.             return (T[]) Arrays.copyOf(elementData, size, a.getClass());  
  125.         // 若数组a的大小 >= ArrayList的元素个数;  
  126.         // 则将ArrayList的全部元素都拷贝到数组a中。  
  127.         System.arraycopy(elementData, 0, a, 0, size);  
  128.         if (a.length > size)  
  129.             a[size] = null;  
  130.         return a;  
  131.     }  
  132.     // 获取index位置的元素值  
  133.     public E get(int index) {  
  134.         RangeCheck(index);  
  135.         return (E) elementData[index];  
  136.     }  
  137.     // 设置index位置的值为element  
  138.     public E set(int index, E element) {  
  139.         RangeCheck(index);  
  140.         E oldValue = (E) elementData[index];  
  141.         elementData[index] = element;  
  142.         return oldValue;  
  143.     }  
  144.     // 将e添加到ArrayList中  
  145.     public boolean add(E e) {  
  146.         ensureCapacity(size + 1);  // Increments modCount!!  
  147.         elementData[size++] = e;  
  148.         return true;  
  149.     }  
  150.     // 将e添加到ArrayList的指定位置  
  151.     public void add(int index, E element) {  
  152.         if (index > size || index < 0)  
  153.             throw new IndexOutOfBoundsException(  
  154.             "Index: "+index+", Size: "+size);  
  155.         ensureCapacity(size+1);  // Increments modCount!!  
  156.         System.arraycopy(elementData, index, elementData, index + 1,  
  157.              size - index);  
  158.         elementData[index] = element;  
  159.         size++;  
  160.     }  
  161.     // 删除ArrayList指定位置的元素  
  162.     public E remove(int index) {  
  163.         RangeCheck(index);  
  164.         modCount++;  
  165.         E oldValue = (E) elementData[index];  
  166.         int numMoved = size - index - 1;  
  167.         if (numMoved > 0)  
  168.             System.arraycopy(elementData, index+1, elementData, index,  
  169.                  numMoved);  
  170.         elementData[--size] = null// Let gc do its work  
  171.         return oldValue;  
  172.     }  
  173.     // 删除ArrayList的指定元素  
  174.     public boolean remove(Object o) {  
  175.         if (o == null) {  
  176.                 for (int index = 0; index < size; index++)  
  177.             if (elementData[index] == null) {  
  178.                 fastRemove(index);  
  179.                 return true;  
  180.             }  
  181.         } else {  
  182.             for (int index = 0; index < size; index++)  
  183.             if (o.equals(elementData[index])) {  
  184.                 fastRemove(index);  
  185.                 return true;  
  186.             }  
  187.         }  
  188.         return false;  
  189.     }  
  190.     // 快速删除第index个元素  
  191.     private void fastRemove(int index) {  
  192.         modCount++;  
  193.         int numMoved = size - index - 1;  
  194.         // 从"index+1"开始,用后面的元素替换前面的元素。  
  195.         if (numMoved > 0)  
  196.             System.arraycopy(elementData, index+1, elementData, index,  
  197.                              numMoved);  
  198.         // 将最后一个元素设为null  
  199.         elementData[--size] = null// Let gc do its work  
  200.     }  
  201.     // 删除元素  
  202.     public boolean remove(Object o) {  
  203.         if (o == null) {  
  204.             for (int index = 0; index < size; index++)  
  205.             if (elementData[index] == null) {  
  206.                 fastRemove(index);  
  207.             return true;  
  208.             }  
  209.         } else {  
  210.             // 便利ArrayList,找到“元素o”,则删除,并返回true。  
  211.             for (int index = 0; index < size; index++)  
  212.             if (o.equals(elementData[index])) {  
  213.                 fastRemove(index);  
  214.             return true;  
  215.             }  
  216.         }  
  217.         return false;  
  218.     }  
  219.     // 清空ArrayList,将全部的元素设为null  
  220.     public void clear() {  
  221.         modCount++;  
  222.         for (int i = 0; i < size; i++)  
  223.             elementData[i] = null;  
  224.         size = 0;  
  225.     }  
  226.     // 将集合c追加到ArrayList中  
  227.     public boolean addAll(Collection<? extends E> c) {  
  228.         Object[] a = c.toArray();  
  229.         int numNew = a.length;  
  230.         ensureCapacity(size + numNew);  // Increments modCount  
  231.         System.arraycopy(a, 0, elementData, size, numNew);  
  232.         size += numNew;  
  233.         return numNew != 0;  
  234.     }  
  235.     // 从index位置开始,将集合c添加到ArrayList  
  236.     public boolean addAll(int index, Collection<? extends E> c) {  
  237.         if (index > size || index < 0)  
  238.             throw new IndexOutOfBoundsException(  
  239.             "Index: " + index + ", Size: " + size);  
  240.         Object[] a = c.toArray();  
  241.         int numNew = a.length;  
  242.         ensureCapacity(size + numNew);  // Increments modCount  
  243.         int numMoved = size - index;  
  244.         if (numMoved > 0)  
  245.             System.arraycopy(elementData, index, elementData, index + numNew,  
  246.                  numMoved);  
  247.         System.arraycopy(a, 0, elementData, index, numNew);  
  248.         size += numNew;  
  249.         return numNew != 0;  
  250.     }  
  251.     // 删除fromIndex到toIndex之间的全部元素。  
  252.     protected void removeRange(int fromIndex, int toIndex) {  
  253.     modCount++;  
  254.     int numMoved = size - toIndex;  
  255.         System.arraycopy(elementData, toIndex, elementData, fromIndex,  
  256.                          numMoved);  
  257.     // Let gc do its work  
  258.     int newSize = size - (toIndex-fromIndex);  
  259.     while (size != newSize)  
  260.         elementData[--size] = null;  
  261.     }  
  262.     private void RangeCheck(int index) {  
  263.     if (index >= size)  
  264.         throw new IndexOutOfBoundsException(  
  265.         "Index: "+index+", Size: "+size);  
  266.     }  
  267.     // 克隆函数  
  268.     public Object clone() {  
  269.         try {  
  270.             ArrayList<E> v = (ArrayList<E>) super.clone();  
  271.             // 将当前ArrayList的全部元素拷贝到v中  
  272.             v.elementData = Arrays.copyOf(elementData, size);  
  273.             v.modCount = 0;  
  274.             return v;  
  275.         } catch (CloneNotSupportedException e) {  
  276.             // this shouldn't happen, since we are Cloneable  
  277.             throw new InternalError();  
  278.         }  
  279.     }  
  280.     // java.io.Serializable的写入函数  
  281.     // 将ArrayList的“容量,所有的元素值”都写入到输出流中  
  282.     private void writeObject(java.io.ObjectOutputStream s)  
  283.         throws java.io.IOException{  
  284.     // Write out element count, and any hidden stuff  
  285.     int expectedModCount = modCount;  
  286.     s.defaultWriteObject();  
  287.         // 写入“数组的容量”  
  288.         s.writeInt(elementData.length);  
  289.     // 写入“数组的每一个元素”  
  290.     for (int i=0; i<size; i++)  
  291.             s.writeObject(elementData[i]);  
  292.     if (modCount != expectedModCount) {  
  293.             throw new ConcurrentModificationException();  
  294.         }  
  295.     }  
  296.     // java.io.Serializable的读取函数:根据写入方式读出  
  297.     // 先将ArrayList的“容量”读出,然后将“所有的元素值”读出  
  298.     private void readObject(java.io.ObjectInputStream s)  
  299.         throws java.io.IOException, ClassNotFoundException {  
  300.         // Read in size, and any hidden stuff  
  301.         s.defaultReadObject();  
  302.         // 从输入流中读取ArrayList的“容量”  
  303.         int arrayLength = s.readInt();  
  304.         Object[] a = elementData = new Object[arrayLength];  
  305.         // 从输入流中将“所有的元素值”读出  
  306.         for (int i=0; i<size; i++)  
  307.             a[i] = s.readObject();  
  308.     }  
  309. }  
  310. </span>  

重点总结:

  • ArrayList 实际上是通过一个数组去保存数据的。当我们构造ArrayList时;若使用默认构造函数,则ArrayList的默认容量大小是10
  • 当ArrayList容量不足以容纳全部元素时,ArrayList会重新设置容量:新的容量=“(原始容量x3)/2 + 1”。
  • ArrayList的克隆函数,即是将全部元素克隆到一个数组中。
  • ArrayList实现java.io.Serializable的方式。当写入到输出流时,先写入“容量”,再依次写入“每一个元素”;当读出输入流时,先读取“容量”,再依次读取“每一个元素”。

三.ArrayList的使用实例

1.ArrayList的添加

将字符a添加到list当中

[java]  view plain  copy
  1. <span style="font-family:Microsoft YaHei;">package com.ArrayList;  
  2.   
  3. import java.util.ArrayList;  
  4.   
  5. /** 
  6.  * @author shengmingqijiquan 
  7.  * @since 2016.09.23 
  8.  *  
  9.  * */  
  10.     public class MyArrayList{  
  11.         public static void main(String[] args) {  
  12.             ArrayList<String> list = new ArrayList<String>();  
  13.             list.add("a");//按照顺序依次添加。将a添加到list中  
  14.             System.out.println(list+" ");  
  15.             list.add(1,"b");//在第1个元素后面添加E,ArrayList中必须有足够多的数据,例如ArrayList中没有任何数据,这个时候使用arraylist.add(1, "E");就会出现java.lang.IndexOutOfBoundsException异常。  
  16.             System.out.println(list+" ");  
  17.             ArrayList<String> list1 = new ArrayList<String>();  
  18.             list1.addAll(list);//将list中的全部数据添加到list1中  
  19.             System.out.println(list1+" ");  
  20.             list1.addAll(1,list);//将一个ArrayList中的所有数据添加到另外一个ArraList中的第1个元素之后  
  21.             System.out.println(list1+" ");  
  22.               
  23.         }  
  24.           
  25. }  
  26. </span>  

运行结果:


2.ArrayList的删除

[java]  view plain  copy
  1. <span style="font-family:Microsoft YaHei;">package com.ArrayList;  
  2.   
  3. import java.util.ArrayList;  
  4. /** 
  5.  * @author shengmingqijiquan 
  6.  * @since 2016.09.23 
  7.  *  
  8.  * */  
  9. public class ArrrayListRemove {  
  10.     public static void main(String[] args) {  
  11.         ArrayList<String> list = new ArrayList<String>();  
  12.         list.add("a");  
  13.         list.add("b");  
  14.         list.add("c");  
  15.         list.add("d");  
  16.         list.add("e");  
  17.         System.out.println(list+" ");  
  18.           
  19.         //1.按照内容删除单个数据.注意:对于int,String,char这样的原始类型数据是可以删除的,但是对于复杂对象,例如自己编写的User类、Person类对象,需要重写equals方法,负责remove方法无法匹配删除。  
  20.         list.remove("a");//将list中的数据"d"删除     
  21.         System.out.println("删除单个数据a:"+list);  
  22.           
  23.         //2.按照集合同时删除多个数据  
  24.         ArrayList<String> list1 = new ArrayList<String>();  
  25.         list1.add("a");  
  26.         list1.add("b");  
  27.         list.removeAll(list1);//按照list1的数据删除list  
  28.         System.out.println("删除多个数据后,清空之前 "+list);  
  29.           
  30.         //3.清空ArrayList  
  31.         list.clear();  
  32.         System.out.println("清空之后 "+list);  
  33.           
  34.     }  
  35. }  
  36. </span>  
运行结果:

3.ArrayList的修改

[java]  view plain  copy
  1. <span style="font-family:Microsoft YaHei;">package com.ArrayList;  
  2.   
  3. import java.util.ArrayList;  
  4. /** 
  5.  * @author shengmingqijiquan 
  6.  * @date 2016.09.23 
  7.  * */  
  8. public class ArrayListSet {  
  9.   
  10.     public static void main(String[] args) {  
  11.         ArrayList<String> list = new ArrayList<>();  
  12.         list.add("a");  
  13.         list.add("b");  
  14.         list.add("c");  
  15.         list.add("d");  
  16.         list.add("e");  
  17.         System.out.println("修改前"+list);  
  18.         list.set(1,"f");  
  19.         list.set(2,"g");  
  20.         System.out.println("修改后"+list);  
  21.     }  
  22.   
  23. }  
  24. </span>  
运行结果:

4.ArrayList的查询

[java]  view plain  copy
  1. <span style="font-family:Microsoft YaHei;">package com.ArrayList;  
  2.   
  3. import java.util.ArrayList;  
  4. /** 
  5.  * @author shengmingqijiquan 
  6.  * @date 2016.09.23 
  7.  * */  
  8. public class ArrayListGet {  
  9.   
  10.     public static void main(String[] args) {  
  11.         ArrayList<String> list = new  ArrayList<>();  
  12.         list.add("a");  
  13.         list.add("b");  
  14.         list.add("c");  
  15.         list.add("d");  
  16.         list.add("e");  
  17.         System.out.println("初始化数组:"+list);  
  18.         String ele = list.get(1);  
  19.         System.out.println("查询到的元素ele:"+ele);  
  20.           
  21.     }  
  22.   
  23. }  
  24. </span>  
运行结果:

5.ArrayList的遍历

ArrayList支持3种遍历方式

  • 第一种,通过迭代器遍历。即通过Iterator去遍历
[java]  view plain  copy
  1. <span style="font-family:Microsoft YaHei;">Integer value = null;  
  2. Iterator iter = list.iterator();  
  3. while (iter.hasNext()) {  
  4.     value = (Integer)iter.next();  
  5. }  
  6. </span>  

  • 第二种,随机访问,通过索引值去遍历
[java]  view plain  copy
  1. <span style="font-family:Microsoft YaHei;">Integer value = null;  
  2. int size = list.size();  
  3. for (int i=0; i<size; i++) {  
  4.     value = (Integer)list.get(i);          
  5. }  
  6. </span>  

  • 第三种,for循环遍历
[java]  view plain  copy
  1. <span style="font-family:Microsoft YaHei;">Integer value = null;  
  2. for (Integer integ:list) {  
  3.     value = integ;  
  4. }</span>  

比较这三种遍历方式的效率

[java]  view plain  copy
  1. <span style="font-family:Microsoft YaHei;">import java.util.*;  
  2. import java.util.concurrent.*;  
  3. /* 
  4.  * @title ArrayList遍历方式和效率的测试程序。 
  5.  * 
  6.  * @author shengmingqijiquan 
  7.  */  
  8. public class ArrayListRandomAccessTest {  
  9.     public static void main(String[] args) {  
  10.         List list = new ArrayList();  
  11.         for (int i=0; i<100000; i++)  
  12.             list.add(i);  
  13.         //isRandomAccessSupported(list);  
  14.         iteratorThroughRandomAccess(list) ;  
  15.         iteratorThroughIterator(list) ;  
  16.         iteratorThroughFor2(list) ;  
  17.   
  18.     }  
  19.     private static void isRandomAccessSupported(List list) {  
  20.         if (list instanceof RandomAccess) {  
  21.             System.out.println("RandomAccess implemented!");  
  22.         } else {  
  23.             System.out.println("RandomAccess not implemented!");  
  24.         }  
  25.     }  
  26.     public static void iteratorThroughRandomAccess(List list) {  
  27.         long startTime;  
  28.         long endTime;  
  29.         startTime = System.currentTimeMillis();  
  30.         for (int i=0; i<list.size(); i++) {  
  31.             list.get(i);  
  32.         }  
  33.         endTime = System.currentTimeMillis();  
  34.         long interval = endTime - startTime;  
  35.         System.out.println("iteratorThroughRandomAccess:" + interval+" ms");  
  36.     }  
  37.     public static void iteratorThroughIterator(List list) {  
  38.         long startTime;  
  39.         long endTime;  
  40.         startTime = System.currentTimeMillis();  
  41.         for(Iterator iter = list.iterator(); iter.hasNext(); ) {  
  42.             iter.next();  
  43.         }  
  44.         endTime = System.currentTimeMillis();  
  45.         long interval = endTime - startTime;  
  46.         System.out.println("iteratorThroughIterator:" + interval+" ms");  
  47.     }  
  48.     public static void iteratorThroughFor2(List list) {  
  49.         long startTime;  
  50.         long endTime;  
  51.         startTime = System.currentTimeMillis();  
  52.         for(Object obj:list)  
  53.   
  54.         endTime = System.currentTimeMillis();  
  55.         long interval = endTime - startTime;  
  56.         System.out.println("iteratorThroughFor2:" + interval+" ms");  
  57.     }  
  58. }  
  59. </span>  
运行结果:
iteratorThroughRandomAccess:3 ms
iteratorThroughIterator:8 ms
iteratorThroughFor2:5 ms
由此可见,遍历ArrayList时,使用随机访问(即,通过索引序号访问)效率最高,而使用迭代器的效率最低!

6.ArrayList之toArray()补充

当我们调用ArrayList中的 toArray(),可能遇到过抛出“java.lang.ClassCastException”异常的情况。下面我们说说这是怎么回事。
ArrayList提供了2个toArray()函数:Object[] toArray()<T> T[] toArray(T[] contents)。调用 toArray() 函数会抛出“java.lang.ClassCastException”异常,但是调用 toArray(T[] contents) 能正常返回 T[]。
toArray() 会抛出异常是因为 toArray() 返回的是 Object[] 数组,将 Object[] 转换为其它类型(如如,将Object[]转换为的Integer[])则会抛出“java.lang.ClassCastException”异常,因为Java不支持向下转型。具体的可以参考前面ArrayList.java的源码介绍部分的toArray()。
解决该问题的办法是调用 <T> T[] toArray(T[] contents) , 而不是 Object[] toArray()。
调用 toArray(T[] contents) 返回T[]的可以通过以下几种方式实现。
[java]  view plain  copy
  1. <span style="font-family:Microsoft YaHei;">// toArray(T[] contents)调用方式一  
  2. public static Integer[] vectorToArray1(ArrayList<Integer> v) {  
  3.     Integer[] newText = new Integer[v.size()];  
  4.     v.toArray(newText);  
  5.     return newText;  
  6. }  
  7. // toArray(T[] contents)调用方式二。最常用!  
  8. public static Integer[] vectorToArray2(ArrayList<Integer> v) {  
  9.     Integer[] newText = (Integer[])v.toArray(new Integer[0]);  
  10.     return newText;  
  11. }  
  12. // toArray(T[] contents)调用方式三  
  13. public static Integer[] vectorToArray3(ArrayList<Integer> v) {  
  14.     Integer[] newText = new Integer[v.size()];  
  15.     Integer[] newStrings = (Integer[])v.toArray(newText);  
  16.     return newStrings;  
  17. }</span>  

7.ArrayList综合实例

import java.util.*;
[java]  view plain  copy
  1. <span style="font-family:Microsoft YaHei;">/* 
  2.  * @title ArrayList常用API的测试程序 
  3.  * @author shengmingqijiquan  
  4.  * @email 1127641712@qq.com 
  5.  */  
  6. public class ArrayListTest {  
  7.     public static void main(String[] args) {  
  8.   
  9.         // 创建ArrayList  
  10.         ArrayList list = new ArrayList();  
  11.         // 将“”  
  12.         list.add("1");  
  13.         list.add("2");  
  14.         list.add("3");  
  15.         list.add("4");  
  16.         // 将下面的元素添加到第1个位置  
  17.         list.add(0"5");  
  18.         // 获取第1个元素  
  19.         System.out.println("the first element is: "+ list.get(0));  
  20.         // 删除“3”  
  21.         list.remove("3");  
  22.         // 获取ArrayList的大小  
  23.         System.out.println("Arraylist size=: "+ list.size());  
  24.         // 判断list中是否包含"3"  
  25.         System.out.println("ArrayList contains 3 is: "+ list.contains(3));  
  26.         // 设置第2个元素为10  
  27.         list.set(1"10");  
  28.         // 通过Iterator遍历ArrayList  
  29.         for(Iterator iter = list.iterator(); iter.hasNext(); ) {  
  30.             System.out.println("next is: "+ iter.next());  
  31.         }  
  32.         // 将ArrayList转换为数组  
  33.         String[] arr = (String[])list.toArray(new String[0]);  
  34.         for (String str:arr)  
  35.             System.out.println("str: "+ str);  
  36.         // 清空ArrayList  
  37.         list.clear();  
  38.         // 判断ArrayList是否为空  
  39.         System.out.println("ArrayList is empty: "+ list.isEmpty());  
  40.     }  
  41. }  
  42. </span>  
运行结果:

原文:http://blog.csdn.net/shengmingqijiquan,谢谢原作者.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值