JAVA List与Array互相转型

本文探讨了Java中转型规则问题及数组对范型的支持,详细解析了转型失败的原因,并通过实例展示了如何正确地进行转型操作。同时,文章深入分析了JDK5引入的泛型对集合类安全性的提升,以及List.toArray方法返回类型为Object[]的原理。最后,文章还讨论了如何将数组转换为List的方法,提供了实用的解决方案。

转载自:http://blog.youkuaiyun.com/zhqingyun163/archive/2009/10/29/4744365.aspx

 

今天写代码遇到一个奇怪的问题,具体代码不贴出了,写一个简化的版本。如下:
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);

转载于:https://www.cnblogs.com/bethunebtj/articles/4843145.html

<think>我们正在处理一个Java编程问题:如何将List<Integer>转换为int[]数组。根据用户的要求,我们需要参考之前提供的引用,特别是引用[1]和引用[3]集合和数组的转换相关。引用[1]是关于将基本类型数组(如int[])转换为List<Integer>,但用户需要的是相反的操作:将List<Integer>转换为int[]。虽然引用[1]不是直接关于这个问题的,但它提醒我们注意基本类型和包装类型之间的转换问题。引用[3]展示了一个将ArrayList转换为数组的例子,但它是转换为Object[]数组,而不是基本类型int[]数组。然而,我们可以从这个例子中借鉴使用toArray()方法。由于用户需要转换为基本类型数组,我们不能直接使用toArray()方法,因为toArray()方法返回的是包装类型的数组(Integer[])。我们需要进一步将Integer[]转换为int[]。因此,我们可以分两步:1.将List<Integer>转换为Integer[]数组。2.将Integer[]数组转换为int[]数组。或者,我们可以使用Java8的StreamAPI来简化转换过程。下面提供几种方法:###方法1:使用循环手动转换```javaList<Integer>list=Arrays.asList(1,2,3,4,5);int[]array=newint[list.size()];for(inti=0;i< list.size();i++){array[i]=list.get(i);}```###方法2:使用Java8StreamAPI```javaList<Integer>list=Arrays.asList(1,2,3,4,5);int[]array=list.stream().mapToInt(i->i).toArray();```###方法3:通过Integer[]数组中转```javaList<Integer>list=Arrays.asList(1,2,3,4,5);Integer[]integerArray=list.toArray(newInteger[0]);int[]array=newint[integerArray.length];for(inti=0;i< integerArray.length;i++){array[i]=integerArray[i];}```其中,方法2(使用StreamAPI)是最简洁和推荐的方式。我们还可以参考引用[5]中的一些思路,虽然它是Python代码,但思路是类似的:检查长度,然后通过索引映射到二维数组。不过我们这里是一维数组转换,不需要检查长度(因为是一对一转换),但要注意如果List为null的情况。因此,我们可以在代码中添加空值检查:###完整示例代码```javaimportjava.util.Arrays;importjava.util.List;publicclassListToIntArrayExample{publicstaticvoidmain(String[]args){List<Integer>list=Arrays.asList(1,2,3,4,5);int[]array=list.stream().mapToInt(Integer::intValue).toArray();System.out.println(Arrays.toString(array));}}```运行结果:[1,2,3,4,5]###注意事项-如果List为null,使用上述代码会抛出NullPointerException。在实际应用中,应确保List不为null,或者进行空值处理。下面生成相关问题:</think> ### Java中将List转换为int数组的方法 在Java中,将`List<Integer>`转换为`int[]`数组需注意基本类型包装类型的区别。以下是几种实现方法及代码示例: #### 方法1:使用Java 8 Stream API(推荐) ```java import java.util.*; import java.util.stream.*; List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); int[] intArray = list.stream() .mapToInt(Integer::intValue) .toArray(); // 输出: [1, 2, 3, 4, 5] ``` #### 方法2:手动循环转换 ```java List<Integer> list = Arrays.asList(1, 2, 3); int[] intArray = new int[list.size()]; for (int i = 0; i < list.size(); i++) { intArray[i] = list.get(i); // 自动拆箱 } ``` #### 方法3:通过Integer[]中转 ```java List<Integer> list = Arrays.asList(8, 9, 10); Integer[] boxedArray = list.toArray(new Integer[0]); int[] intArray = Arrays.stream(boxedArray) .mapToInt(Integer::intValue) .toArray(); ``` #### 方法4:使用Apache Commons Lang库 ```java int[] intArray = ArrayUtils.toPrimitive( integerList.toArray(new Integer[0]) ); ``` #### ⚠️ 关键注意事项 1. **避免空指针** 如果List包含`null`值,`mapToInt()`会抛出`NullPointerException`: ```java // 安全处理: int[] safeArray = list.stream() .mapToInt(i -> (i == null) ? 0 : i) .toArray(); ``` 2. **类型限制** 方法仅适用于`List<Integer>`,其他类型(如`List<String>`)需要先转型或值转换[^1][^3]。 3. **性能考量** - ✅ **Stream API**:代码简洁,并行处理大数据集更优 - ✅ **手动循环**:小数据集效率更高 --- ### 相关问题 1. 如何将`int[]`数组转换回`List<Integer>`? 2. Java中基本类型数组集合互转时有哪些常见陷阱? 3. 为什么Java的集合类不能直接存储基本类型(如`int`)? 4. Java 8 Stream API在处理集合时还有哪些常用转换操作? [^1]: Java原始数组转换为List的两种方式差异。[原始引用](https://example.com/conversion-snippets) [^3]: ArrayList转数组的`toArray()`方法使用示例。[原始引用](https://example.com/arraylist-example)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值