Java中List转换为Array与Array转换为List

本文探讨了Java中数组和ArrayList在类型转换时遇到的问题,特别是如何正确地将泛型ArrayList转换为特定类型的数组,以及Java对泛型数组的支持限制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 转自【http://hi.baidu.com/fandywang_jlu/blog/item/9daf25175be717094a90a7a6.html

 

今天写代码遇到一个奇怪的问题,具体代码不贴出了,写一个简化的版本。如下:
ArrayList<String> list=new ArrayList<String>();
String strings[]=(String [])list.toArray();

这样写代码个人觉得应该没什么问题,编译也没有问题。可是具体运行的时候报异常,如下:Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object;
但是这么写是没有问题的:
ArrayList<String> list=new ArrayList<String>();
         String strings[]=new String[list.size()];
         for(int i=0,j=list.size();i<j;i++){
             strings[i]=list.get(i);
         }
对于这个现象我们可以这么解释:Java中允许向上和向下转型,但是这个转型是否成功是根据Java虚拟机中这个对象的类型来实现的。Java虚拟机中保存了每个对象的类型。而数组也是一个对象。数组的类型是[Ljava.lang.Object。把[Ljava.lang.Object转换成[Ljava.lang.String是显然不可能的事情,因为这里是一个向下转型,而虚拟机只保存了这是一个Object的数组,不能保证数组中的元素是String的,所以这个转型不能成功。数组里面的元素只是元素的引用,不是存储的具体元素,所以数组中元素的类型还是保存在Java虚拟机中的。

根据上面的解释,我们可以把这个问题归纳到下面这个模型:
Object objs[]=new Object[10];
String strs[]=(String[])objs;

这样子和刚才上面编译错误是一样的。如果我们修改一下这个代码,如下:
String strs[]=new String[10];
Object objs[]=strs;

这样子就可以编译通过了。所以这个问题我们可以归结为一个Java转型规则的问题。下面谈一下Java数组对范型的支持问题。

JDK5中已经有了对范型的支持,这样可以保证在集合和Map中的数据类型的安全,可是,List的toArray方法返回的竟然是Object []让人很迷惑。个人感觉应该可以根据范型,直接返回相应的T []。仔细看了一下JDK的源码发现List转化为array有两个方法:

public Object[] toArray();
这个方法把List中的全部元素返回一个相同大小的数组,数组中的所有元素都为Object类型。

public <T> T[] toArray(T[] a);
这个方法把List中的全部元素返回一个相同大小的数组,数组中的所有元素都为T类型。

List如此设计是因为Java编译器不允许我们new范型数组。也就是说你不能这么定义一个数组:
T arr=new T[size];

但是你却可以用T[]来表示数组,而且可以把数组强制转化为T[]。比如List中的public <T> T[] toArray(T[] a)是这么实现的:
     public <T> T[] toArray(T[] a) {
         if (a.length < size)
             a = (T[])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.getClass().getComponentType()方法是取得一个数组元素的类型)。

最终,List转换为Array可以这样处理:

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

String[] strings = new String[list.size()];

list.toArray(strings);

反过来,如果要将数组转成List怎么办呢?如下:

String[] s = {"a","b","c"}; 
List list = java.util.Arrays.asList(s);

### 回答1: 在 Java 中,可以使用 `toArray()` 方法将 `List` 转换为数组。 例如,如果你有一个 `List<String>` 变量 `list`,你可以使用以下代码将它转换为 `String` 数组: ``` String[] array = list.toArray(new String[0]); ``` 如果你想将 `List` 转换为不同类型的数组,可以指定不同的数组类型。例如,如果你想将 `List<Integer>` 转换为 `int` 数组,你可以使用以下代码: ``` int[] array = list.stream().mapToInt(i -> i).toArray(); ``` 注意,这种方法只能用于将 `List` 转换为基本类型数组,如 `int`、`double`、`float` 等。对于对象类型的数组,你需要使用 `toArray(T[] a)` 方法。 另外,也可以使用 `List.toArray(T[] a)` 方法将 `List` 转换为数组,其中 `T` 指定数组元素的类型。例如,如果你想将 `List<String>` 转换为 `String` 数组,你可以使用以下代码: ``` String[] array = list.toArray(new String[list.size()]); ``` 这种方法的优点是可以直接指定转换后的数组的大小,因此不会出现转换后数组大小和 `List` 大小不一致的情况。 ### 回答2: 在Java中,我们可以使用ListArray之间的转换来实现数据类型的互相转换。 要将List转换Array,我们可以使用List的toArray()方法。这个方法返回一个包含List中所有元素的新数组。可以将这个新数组的类型指定为List中存储元素的类型的数组。以下是一个示例代码: List<String> list = new ArrayList<>(); list.add("Java"); list.add("Python"); list.add("C++"); String[] array = list.toArray(new String[0]); 在这个示例中,我们首先创建一个包含String类型元素的List。然后,我们使用List的toArray()方法将这个List转换String[]类型的数组。在这个方法中,我们传递一个新的String数组作为参数。如果我们传递一个长度为0的数组作为参数,toArray()方法将返回一个新的String数组,其中包含List中的所有元素。 要将数组转换List,我们可以使用Arrays类的asList()方法。这个方法返回一个包含指定数组所有元素的List。以下是一个示例代码: String[] array = {"Java", "Python", "C++"}; List<String> list = Arrays.asList(array); 在这个示例中,我们首先创建一个包含String类型元素的数组。然后,我们使用Arrays类的asList()方法将这个数组转换为一个List。在这个方法中,我们传递数组作为参数,并将返回的List赋值给新的List变量。 需要注意的是,使用asList()方法转换List实际上是一个固定大小的List,不能调整其大小。如果我们尝试对这个List进行添加或删除操作,将会抛出UnsupportedOperationException异常。 ### 回答3: 要将JavaList转换为数组,您可以使用List的toArray()方法。这个方法将返回一个List相对应的数组。 ```java List<String> list = new ArrayList<>(); list.add("Apple"); list.add("Banana"); list.add("Orange"); String[] array = list.toArray(new String[0]); ``` 在这个例子中,我们首先创建一个ArrayListString类型的List对象,并向其中添加了三个元素。然后,我们调用List的toArray()方法,并将其传入我们希望返回的数组类型。为了获得一个String类型的数组,我们传入了一个空的String数组,通过这个空数组的类型来确定返回的数组类型。 如果您不使用提供的空数组, toArray()方法将会返回一个Object类型的数组。但是请注意,传递给toArray()方法的空数组大小并不影响结果数组的大小,它仅仅用于确定返回数组的类型。 转换后,我们可以通过循环遍历原始List和新的数组来进行比较。 ```java for (String element : list) { System.out.println(element); } for (String element : array) { System.out.println(element); } ``` 这样,我们就可以将一个JavaList对象转换为相应类型的数组,以便在需要使用数组的代码中使用。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值