网站开发报价人天,网页设计制作实训总结,网新企业网站管理系统,公司网站制作 步骤作者 | 大脑补丁来源 | blog.csdn.net/x541211190/article/details/79597236前言#xff1a;本文介绍Java中数组转为List三种情况的优劣对比#xff0c;以及应用场景的对比#xff0c;以及程序员常犯的类型转换错误原因解析。一.最常见方式#xff08;未必最佳#xff09;… 作者 | 大脑补丁来源 | blog.csdn.net/x541211190/article/details/79597236前言本文介绍Java中数组转为List三种情况的优劣对比以及应用场景的对比以及程序员常犯的类型转换错误原因解析。一.最常见方式未必最佳通过 Arrays.asList(strArray) 方式,将数组转换List后不能对List增删只能查改否则抛异常。关键代码List list Arrays.asList(strArray);private void testArrayCastToListError() {String[] strArray new String[2];List list Arrays.asList(strArray);//对转换后的list插入一条数据list.add(1);System.out.println(list);
}
执行结果Exception in thread main java.lang.UnsupportedOperationExceptionat java.util.AbstractList.add(AbstractList.java:148)at java.util.AbstractList.add(AbstractList.java:108)at com.darwin.junit.Calculator.testArrayCastToList(Calculator.java:19)at com.darwin.junit.Calculator.main(Calculator.java:44)
程序在list.add(“1”)处抛出异常UnsupportedOperationException。原因解析Arrays.asList(strArray)返回值是java.util.Arrays类中一个私有静态内部类java.util.Arrays.ArrayList它并非java.util.ArrayList类。java.util.Arrays.ArrayList类具有 set()get()contains()等方法但是不具有添加add()或删除remove()方法,所以调用add()方法会报错。使用场景Arrays.asList(strArray)方式仅能用在将数组转换为List后不需要增删其中的值仅作为数据源读取使用。二.数组转为List后支持增删改查的方式通过ArrayList的构造器将Arrays.asList(strArray)的返回值由java.util.Arrays.ArrayList转为java.util.ArrayList。关键代码ArrayListString list new ArrayListString(Arrays.asList(strArray)) ;private void testArrayCastToListRight() {String[] strArray new String[2];ArrayListString list new ArrayListString(Arrays.asList(strArray)) ;list.add(1);System.out.println(list);
}
执行结果成功追加一个元素“1”。[null, null, 1]
使用场景需要在将数组转换为List后对List进行增删改查操作在List的数据量不大的情况下可以使用。三.通过集合工具类Collections.addAll()方法(最高效)通过Collections.addAll(arrayList, strArray)方式转换根据数组的长度创建一个长度相同的List然后通过Collections.addAll()方法将数组中的元素转为二进制然后添加到List中这是最高效的方法。关键代码ArrayList String arrayList new ArrayListString(strArray.length);
Collections.addAll(arrayList, strArray);
测试private void testArrayCastToListEfficient(){String[] strArray new String[2];ArrayList String arrayList new ArrayListString(strArray.length);Collections.addAll(arrayList, strArray);arrayList.add(1);System.out.println(arrayList);
}
执行结果同样成功追加一个元素“1”。[null, null, 1]
使用场景需要在将数组转换为List后对List进行增删改查操作在List的数据量巨大的情况下优先使用可以提高操作速度。注附上Collections.addAll()方法源码public static T boolean addAll(Collection? super T c, T... elements) {boolean result false;for (T element : elements)result | c.add(element);//result和c.add(element)按位或运算,然后赋值给resultreturn result;
}
四.Java8可通过stream流将3种基本类型数组转为List如果JDK版本在1.8以上可以使用流stream来将下列3种数组快速转为List分别是int[]、long[]、double[]其他数据类型比如short[]、byte[]、char[]在JDK1.8中暂不支持。由于这只是一种常用方法的封装不再纳入一种崭新的数组转List方式暂时算是java流送给我们的常用工具方法吧。转换代码示例如下ListInteger intList Arrays.stream(new int[] { 1, 2, 3, }).boxed().collect(Collectors.toList());
ListLong longList Arrays.stream(new long[] { 1, 2, 3 }).boxed().collect(Collectors.toList());
ListDouble doubleList Arrays.stream(new double[] { 1, 2, 3 }).boxed().collect(Collectors.toList());
如果是String数组可以使用Stream流这样转换String[] arrays {tom, jack, kate};
ListString stringList Stream.of(arrays).collect(Collectors.toList());
补充回答评论中的疑问问题 有评论提出数组类型如果是整型数组转为List时会报错答案 在JDK1.8环境中测试这三种转换方式是没有问题的。放心使用。对于Integer[]整型数组转List的方法和测试结果如下方式一不支持增删Integer[] intArray1 new Integer[2];
ListInteger list1 Arrays.asList(intArray1);
System.out.println(list1);
123
运行结果[null, null]
方式二支持增删Integer[] intArray2 new Integer[2];
ListInteger list2 new ArrayListInteger(Arrays.asList(intArray2)) ;
list2.add(2);
System.out.println(list2);
运行结果[null, null, 2]
方式三支持增删且数据量大最高效Integer[] intArray3 new Integer[2];
ListInteger list3 new ArrayListInteger(intArray3.length);
Collections.addAll(list3, intArray3);
list3.add(3);
System.out.println(list3);
运行结果[null, null, 3]
综上整型Integer[]数组转ListInteger的正确方式应该是这样的。猜想你们遇到的问题 由于评论没有给出报错的代码所以我猜想你们出现的错误可能是这样转换的int[] intArray1 new int[2];
ListInteger list1 Arrays.asList(intArray1);//此处报错
报错原因等号两边类型不一致当然编译不通过。分析见下文。那么在声明数组时用int[] 还是Integer[]哪种声明方式才能正确的转为List呢答案 只能用Integer[]转ListInteger即只能用基本数据类型的包装类型才能直接转为List。原因分析如下我们来看List在Java源码中的定义别害怕看不懂源码看我分析很易懂的public interface ListE extends CollectionE {省略…}
再来看Arrays.asList()的在Java源码定义public static T ListT asList(T... a) {return new ArrayList(a);
}
从上述源码中可以看出List声明时需要传递一个泛型E作为形参asList()参数类型也是泛型中的通配类型T。Java中所有的泛型必须是引用类型。什么是引用类型Integer是引用类型那int是什么类型int是基本数据类型不是引用类型。这就是为什么java中没有Listint而只有ListInteger。举一反三其他8种基本数据类型byte、short、int、long、float、double、char也都不是引用类型所以8种基本数据类型都不能作为List的形参。但String、数组、class、interface是引用类型都可以作为List的形参所以存在ListRunnable接口类型的集合、Listint[]数组类型的集合、ListString类的集合。但不存在listbyte、listshort 等基本类型的集合。有了上述基础知识后再来看为什么下面两行代码第二行能编译通过第三行却编译报错int[] intArray1 new int[1];
Arrays.asList(intArray1);//编译不报错
ListInteger list1 Arrays.asList( intArray1);//编译报错
答案第二行代码Arrays.asList()方法的入参是个引用类型的int[],那么返回值类型一定是Listint[] ,其完整代码是Listint[] intsArray Arrays.asList(intArray1);所以编译通过没问题。第三行报错因为等号两边的类型不一致左边ListInteger,右边Listint[]所以编译时就报错。总结现在你应该明白为什么int[]不能直接转换为ListInteger而Integer[]就可以转换为ListInteger了吧。因为List中的泛型必须是引用类型int是基本数据类型不是引用类型但int的包装类型Integer是class类型属于引用类型所以Integer可以作为List形参ListInteger在java中是可以存在的但不存在Listint类型。在编码时我们不光要知其然还要知其所以然通过分析JDK源码才能得出一手信息不仅了解到了如何用还能得出为何这样用。
往期推荐
23张图万字详解「链表」从小白到大佬队列实现栈的3种方法全都击败了100%的用户聊聊近期的感受和10月文章精选小白学算法买卖股票的最佳时机关注我每天陪你进步一点点