ArrayList.toArray()

来源:互联网 发布:蚁群优化 编辑:程序博客网 时间:2024/06/14 19:12

ArrayList.toArray()时,出现java.lang.ClassCastException的错误。

ArrayList类扩展AbstractList并执行List接口。ArrayList支持可随需要而增长的动态数组。

    ArrayList有如下的构造函数:
        ArrayList( )
        ArrayList(Collection c)
        ArrayList(int capacity)

如果调用new ArrayList()构造时,其默认的capacity(初始容量)为10。

参见ArrayList源码,其中是这样定义的:

    public ArrayList() {
  this(10);
     }

默认初始化内部数组大小为10。

程序编译后执行ArrayList.toArray(),把ArrayList转化为数组时,该数组大小仍为capacity(为10)。

当装入的数据和capacity值不等时(小于capacity),比如只装入了5个数据,数组中后面的(capacity - size)个对象将置为null,此时当数组强制类型转换时,容易出现一些问题,如java.lang.ClassCastException异常等。

解决办法是:

1.在用ArrayList转化为数组装数据后,使用trimToSize()重新设置数组的真实大小。

2.String[] myStringArray = (String[])ArrayList.toArray(new String[0]);   //注意此处的写法

public Object[] toArray() {
  Object[] result = new Object[size];
  System.arraycopy(elementData, 0, result, 0, size);
  return result;
}

返回ArrayList元素的一个数组,注意这里虽然生成了一个新的数组,但是数组元素和集合中的元素是共享的,Collection接口中说这个是安全的,这是不严格的。

下面的例子演示了这个效果。
   ArrayList al=new ArrayList();
   al.add(new StringBuffer("hello"));
   Object[] a=al.toArray();
   StringBuffer sb=(StringBuffer)a[0];
   sb.append("changed");  //改变数组元素同样也改变了原来的ArrayList中的元素
   System.out.println(al.get(0));    

这里不要用String来代替StringBuffer,因为String是常量。

ArrayList.toArray()之二:

public Object[] toArray(Object a[]) {
  if (a.length < size)
    a = (Object[])java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size);
   System.arraycopy(elementData, 0, a, 0, size);
   if (a.length > size)
      a[size] = null;
   return a;
}

这个方法有可能不需要生成新的数组,注意到如果数组a容量过大,只在size处设置为null。

如果这个数组a足够大,就会把数据全放进去,返回的数组也是指向这个数组,(数组多余的空间存储的是null对象);要是不够大,就申请一个跟参数同样类型的数组,把值放进去,然后返回。

原创粉丝点击