Java中toArray的用法探究(java数组与list转换)

一.             Incident

import Java.util.ArrayList;

import java.util.List;

public class Test {

public static void main(String[] args) {

List<String> list = new ArrayList<String>();

list.add("1");

list.add("2");

String[] tt =(String[]) list.toArray(new String[0]);

}

}

这段代码是没问题的,但我们看到String[] tt =(String[]) list.toArray(new String[0]) 中的参数很奇怪,然而去掉这个参数new String[0]却在运行时报错。。。

二.             Root Cause Analysis

经研究发现toArray有两个方法:

public Object[] toArray() {

Object[] result = new Object[size];

System.arraycopy(elementData, 0, result, 0, size);

return result;

}

不带参数的toArray方法,是构造的一个Object数组,然后进行数据拷贝,此时进行转型就会产生ClassCastException,这也就是上述问题的root cause了。

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;

}

而带参数的toArray方法,则是根据参数数组的类型,构造了一个对应类型的,长度跟ArrayList的size一致的空数组,虽然方法本身还是以 Object数组的形式返回结果,不过由于构造数组使用的ComponentType跟需要转型的ComponentType一致,就不会产生转型异常。

三.             Solutions

因此在使用toArray的时候可以参考以下三种方式

1. Long[] l = new Long[<total size>];

list.toArray(l);

2. Long[] l = (Long[]) list.toArray(new Long[0]);

3. Long[] a = new Long[<total size>];

Long[] l = (Long[]) list.toArray(a);

四.Further Consideration

该容器中的元素已经用泛型限制了,那里面的元素就应该被当作泛型类型的来看了,然而在目前的java中却不是的,当直接String[] tt =(String[]) list.toArray()时,运行报错。回想一下,应该是java中的强制类型转换只是针对单个对象的,想要偷懒,将整个数组转换成另外一种类型的数组是不行的,这和数组初始化时需要一个个来也是类似的。

以上From:    http://hi.baidu.com/%B4%CB%D6%D0%D3%D0%D5%E6%B5%C0/blog/item/8add93ec812dc9deb31cb1b0.html

[java] view plain copy

  1. import java.util.*;
  2. class testList{
  3. public static void main(String[] args){
  4. //List<Character> list = new ArrayList<Character>();
  5. String[] str = "a b c".split(" ");
  6. System.out.println("字符串数组str,长度为:" + str.length);
  7. for(String c : str)
  8. System.out.println(c);
  9. List<Integer> list = new ArrayList<Integer>();
  10. list.add(1);
  11. list.add(2);
  12. list.add(3);
  13. list.add(4);
  14. Iterator<Integer> it = list.iterator();
  15. System.out.println("整型List list");
  16. while(it.hasNext())
  17. {
  18. System.out.println(it.next());
  19. }
  20. //数组转换成List
  21. List<String> li = new ArrayList<String>();
  22. li = Arrays.asList(str);
  23. Iterator<String> its = li.iterator();
  24. System.out.println("数组str -> list:");
  25. while(its.hasNext())
  26. {
  27. System.out.println(its.next());
  28. }
  29. //List转换成数组
  30. Integer[] b = (Integer[])list.toArray(new Integer[0]);
  31. System.out.println("List list -> 数组b");
  32. for(Integer i : b)
  33. System.out.println(i);
  34. //数组的fill方法
  35. int[] a = new int[5];
  36. Arrays.fill(a,0);
  37. System.out.println("数组a被0填充");
  38. for(int i : a)
  39. System.out.println(i);
  40. }
  41. }
时间: 2024-10-05 04:09:20

Java中toArray的用法探究(java数组与list转换)的相关文章

Java中输入的用法

Java中输入 1. 读取输入 1)构建一个Scanner,附属到System.in Scanner in = new Scanner(System.in); 此时可以使用Scanner类的各种方法来读取输入.例如:nextLine方法来读取一行输入 System.out.print("What is your name?"); String name = in.nextLine(); nextLine():    读取的一行中可能包含空格 next():           读取单个

Java中List的用法

List接口对Collection进行了简单的扩充. 它的具体实现类常用的有ArrayList和LinkedList. ArrayList从其命名中可以看出它是以一种类似数组的形式存储,因此它的随机访问速度极快,但插入和移除元素的速度很慢. LinkedList的内部实现是链表,它适合于在链表中间需要频繁进行插入和删除操作,不适合随机访问,LinkedList可以当作堆栈.队列和双向队列使用. 一个List可以生成ListIterator,使用它可以从两个方向遍历List,也可以从List中间插

跟王老师学集合(十一)java中Comparator的用法

Java中Comparator的用法 主讲人:王少华  QQ群号:483773664 在java中,如果要对集合对象或数组对象进行排序,需要实现Comparator接口以达到我们想要的目标. 接下来我们模拟下在集合对象中对日期属性进行排序 一.实体类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package chapter07_11; public class Person {     private int a

关于时间,日期,星期,月份的算法(Java中Calendar的用法)(一)

package cn.outofmemory.codes.Date; import java.util.Calendar; import java.util.Date; public class CalendarDemo { public static void main(String[] args) { Calendar calendar=Calendar.getInstance(); calendar.setTime(new Date()); System.out.println("如今时间

java中stringBuilder的用法

java中stringBuilder的用法 String对象是不可改变的.每次使用 System.String类中的方法之一时,都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间.在需要对字符串执行重复修改的情况下,与创建新的 String对象相关的系统开销可能会非常昂贵.如果要修改字符串而不创建新的对象,则可以使用System.Text.StringBuilder类.例如,当在一个循环中将许多字符串连接在一起时,使用 StringBuilder类可以提升性能. 通过用一个重载的

java成神之——java中string的用法

java中String的用法 String基本用法 String分割 String拼接 String截取 String换行符和format格式化 String反转字符串和去除空白字符 String获取指定位置字符和replace的使用 StringBuffer的使用 字符串转换 基本类型的转换 添加字符编码 Base64的编码和解码 结语 java中String的用法 String基本用法 字符串一旦创建在堆中就不可变 字符串声明 String str = "你好"; String s

Java中System.setProperty()用法

Java中System.setProperty()用法 /* * 设置指定键对值的系统属性 * setProperty (String prop, String value); *  * 参数: * prop - 系统属性的名称. * value - 系统属性的值.   *  * 返回: * 系统属性以前的值,如果没有以前的值,则返回 null. *  * 抛出:   * SecurityException - 如果安全管理器存在并且其 checkPermission 方法不允许设置指定属性. 

Java基础知识强化106:Java中如何实现十进制到其他进制的转换

下面是示例代码,我们直接通过JDK工具库中的方法实现的,如下: 1 package com.himi.radix; 2 3 4 /** 5 * Java中如何实现十进制到其他进制的转换 6 * @author hebao 7 * 8 */ 9 public class IntegerToOther { 10 11 public static void main(String[] args) { 12 int n = 14; 13 //十进制转成十六进制: 14 String n0 = Integ

Java中Synchronized的用法

版权声明:本文为博主原创文章,未经博主允许不得用于任何商业用途,转载请注明出处. 目录(?)[+] 原文:http://blog.csdn.net/luoweifu/article/details/46613015 作者:luoweifu 转载请标名出处 <编程思想之多线程与多进程(1)--以操作系统的角度述说线程与进程>一文详细讲述了线程.进程的关系及在操作系统中的表现,这是多线程学习必须了解的基础.本文将接着讲一下Java线程同步中的一个重要的概念synchronized. synchro