今天我们主要来说一说List操作在实际使用中有哪些坑,以及面对这些坑的时候我们要怎么解决。
在实际的业务开发中,我们通常会进行数组转List的操作,通常我们会使用Arrays.asList来进行转换
但是在转换基本类型的数组的时候,却出现转换的结果和我们想象的不一致。
上代码
- int[] arr = {1, 2, 3};
- List list = Arrays.asList(arr);
- System.out.println(list.size());
- // 1
- 复制代码
实际上,我们想要转成的List应该是有三个对象而现在只有一个
- public static List asList(T... a) {
- return new ArrayList<>(a);
- }
- 复制代码
可以观察到 asList方法 接收的是一个泛型T类型的参数,T继承Object对象
所以通过断点我们可以看到把 int数组 整体作为一个对象,返回了一个 List

那我们该如何解决呢?
方案一:Java8以上,利用Arrays.stream(arr).boxed()将装箱为Integer数组
- List collect = Arrays.stream(arr).boxed().collect(Collectors.toList()); System.out.println(collect.size());
- System.out.println(collect.get(0).getClass());
- // 3
- // class java.lang.Integer
- 复制代码
方案二:声明数组的时候,声明类型改为包装类型
- Integer[] integerArr = {1, 2, 3};
- List integerList = Arrays.asList(integerArr);
- System.out.println(integerList.size()); System.out.println(integerList.get(0).getClass());
- // 3
- // class java.lang.Integer
- 复制代码
我们将数组对象转成List数据结构之后,竟然不能进行增删操作了
- private static void asListAdd(){
- String[] arr = {"1", "2", "3"};
- List<String> strings = new ArrayList<>(Arrays.asList(arr));
- arr[2] = "4";
- System.out.println(strings.toString());
- Iterator<String> iterator = strings.iterator();
- while (iterator.hasNext()){
- if ("4".equals(iterator.next())){
- iterator.remove();
- }
- }
- strings.forEach(val ->{
- strings.remove("4");
- strings.add("3");
- });
-
-
- System.out.println(Arrays.asList(arr).toString());
- }
-
- [1, 2, 4]
- Exception in thread "main" java.lang.UnsupportedOperationException at java.util.AbstractList.remove(AbstractList.java:161) at java.util.AbstractList$Itr.remove(AbstractList.java:374) at java.util.AbstractCollection.remove(AbstractCollection.java:293) at JavaBase.List.AsListTest.lambda$asListAdd$0(AsListTest.java:47) at java.util.Arrays$ArrayList.forEach(Arrays.java:3880) at JavaBase.List.AsListTest.asListAdd(AsListTest.java:46) at JavaBase.List.AsListTest.main(AsListTest.java:20)
- 复制代码
初始化一个字符串数组,将字符串数组转换为 List,在遍历List的时候进行移除和新增的操作
抛出异常信息UnsupportedOperationException。
根据异常信息java.lang.UnsupportedOperationException,我们看到他是从AbstractList里面出来的,让我们进入源码一看究竟
我们在什么时候调用到了这个 AbstractList 呢?
其实 Arrays.asList(arr) 返回的 ArrayList 不是 java.util.ArrayList,而是 Arrays的内部类
- private static class ArrayList
extends AbstractList - implements RandomAccess, java.io.Serializable{
- private static final long serialVersionUID = -2764017481108945198L;
- private final E[] a;
- ArrayList(E[] array) {
- a = Objects.requireNonNull(array);
- }
-
- @Override
- public E get(int index) {}
-
- @Override
- public E set(int index, E element) {...}
-
- ...
- }
- public abstract class AbstractList
extends AbstractCollection implements List { - public boolean add(E e) {
- add(size(), e);
- return true;
- }
- public void add(int index, E element) {
- throw new UnsupportedOperationException();
- }
-
- public E remove(int index) {
- throw new UnsupportedOperat