一、array 转 list
1️⃣直接使用Arrays的asList方法
String[] str = new String[]{"a", "b", "c"};
List list = Arrays.asList(str);
2️⃣for循环方式
String[] str = new String[]{"a", "b", "c"};
List list = new ArrayList<>();
for (int i = 0; i < str.length; i++) {
list.add(str[i]);
}
二、array 与 Set 的互转
三、list 转 array
public static void main(String[] args) {
List list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");
String str[] = (String[]) list.toArray();
System.out.println(str);
}
编译虽通过,但运行时报Exception in thread “main” java.lang.ClassCastException: [Ljava.lang.Object;
。正确的写法如下:
String str[] = new String[list.size()];
for (int i = 0; i < list.size(); i++) {
str[i] = list.get(i);
}
解释:Java中允许向上和向下转型,但是这个转型是否成功是根据Java虚拟机(JVM)中这个对象的类型来实现的。JVM中保存了每个对象的类型,而数组也是一个对象,数组的类型是[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 转型规则的问题。JDK5 中,Java 数组开始支持范型,这样可以保证在集合和 Map 中的数据类型的安全。可是,List 的 toArray() 返回的竟然是 Object [] 让人很迷惑。开发者可以根据范型,直接返回相应的 T[]。查看 JDK 源码,发现 List 转化为 array 有两个方法:
1️⃣public Object[] toArray();
该方法把 List 中的全部元素返回一个相同大小的数组,数组中的所有元素都为 Object 类型。
2️⃣public T[] toArray(T[] a);
该方法把 List 中的全部元素返回一个相同大小的数组,数组中的所有元素都为 T 类型。
List 如此设计是因为 Java 编译器不允许 new 范型数组。也就是说不能这么定义一个数组:T arr=new T[size];
。但是却可以用 T[] 来表示数组,而且可以把数组强制转化为 T[]。比如 List 中的public T[] toArray(T[] a)
是这么实现的:
public 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);
}else if (a.length > size){
a[size] = null;
}
return a;
}
由上,因为不知道这个数组的类型,必须通过反射机制创建这个数组(a.getClass().getComponentType()
是取得一个数组元素的类型)。最终,List 转换为 Array 可以这样处理:
ArrayList list=new ArrayList();
String[] str= new String[list.size()];
list.toArray(str);
反过来,如将数组转换为 List 如下:
String[] str = {"a","b","c"};
List list = java.util.Arrays.asList(str);