UnsupportedOperationException之数组和List集合之间的转换

标题
数组和List集合之间的转换

前言:本文介绍数组和list集合之间的转换,通过源码的形式解释各种方法的优劣,通过阅读本篇文章,在实际开发避免步入坑中。

一、数组转List

以此数组为例:
String []str={"abc","def","123"};

1. 方法一、使用for循环将数组元素添加到list集合中

        List<String> list=new ArrayList<>(str.length);
        for(String str1:str){
            list.add(str1);
        }
        System.out.println(list.toString());//输出[abc, def, 123]

  此例采用传统的for循环遍历,可以明显看到,使用for循环遍历,并且且需要一个一个添加到集合中,对于数据量大的数组来说,非常耗时,并不推荐使用。

2. 方法二、使用Arrays.asList()方法(慎用)

        list= Arrays.asList(str);
        //list.remove(0);  此处将抛出UnsupportedOperationException异常
        //list.add("add");  此处将抛出UnsupportedOperationException异常
        System.out.println(list.toString());//输出[abc, def, 123]
        str[2]="update";  //修改数组的元素会影响list集合
        System.out.println(list.toString());//输出[abc, def, update]
        list.set(2,"asList");//修改list集合的元素会影响数组的内容
        System.out.println(list.toString());//输出[abc, def, asList]

  此方法将数组转换List后,不能对List增删,只能查改,否则将抛出异常,下来我们来看下一源码是如何实现的:

    public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }
    private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable
    {
        private static final long serialVersionUID = -2764017481108945198L;
        private final E[] a;
        ArrayList(E[] array) {
            a = Objects.requireNonNull(array);
        }
		//此处省略size()  方法
		//此处省略 toArray()  方法
		//此处省略 get()  方法
		//此处省略 set()  方法
		//此处省略 indexOf()  方法
		//此处省略 contains()  方法
		//此处省略 spliterator()  方法
		//此处省略 forEach()  方法
		//此处省略 replaceAll()  方法
		//此处省略 sort()  方法
    }

  通过源码我们可以看到Arrays.asList()方法返回是私有静态内部类java.util.Arrays.ArrayList,并不是java.util.ArrayList类,该内部类继承自AbstractList类,仅有重写set、get方法等,并没有重写add、remove方法,所以很好的解释为什么我们在返回的list中调用add和remove方法抛出异常了。

3. 使用ArrayList的构造方法

        List<String> list2=new ArrayList<>(Arrays.asList(str1));
        System.out.println(list2.toString());//输出[abc, def, 123]

  通过此构造方法我们可以得到一个list集合,仅仅适用于数据量小的时候采用。

4. 使用Collections.addAll() [官方推荐使用的方法]

        List<String> list3=new ArrayList<>(str1.length);
        Collections.addAll(list3,str1);
        System.out.println(list3.toString());//输出[abc, def, 123]

& & Collections.addAll()方法,将数组中的元素转为二进制,然后添加到List中,这是最高效的方法(底层次用的是位运算)。源码如下:

    public static <T> boolean addAll(Collection<? super T> c, T... elements) {
        boolean result = false;
        for (T element : elements)
            result |= c.add(element);
        return result;
    }

5. jdk1.8新增使用Arrays的stream

        List<String> list4 = Arrays.stream(str1).collect(Collectors.toList());
        System.out.println(list4);//输出[abc, def, 123]

  此方法是jdk1.8之后新增的通过stream流的方式来进行转换。

6. jdk1.9使用List.of(),返回的是*【不可变的】*

List<String> list3=List.of(str);

  使用前提:当集合中存储的元素个数已经确定,不再改变。此方法为 Java9新增方法,定义在List接口内,并且为静态方法,故可以由类名直接调用。

7. 方式七:使用CollectionUtils.arrayToList()

        List<String> list5= CollectionUtils.arrayToList(str1);
        System.out.println(list5);
补充一点:当我们使用Arrays.asList()进行转换时,数组的类型引用类型的。
    public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }

  该方法参数是一个泛型T类型的,且返回的类型也是带有泛型的,因此就可以解释,数组的类型为什么必须是引用类型的,因为泛型必须是引用类型的。

二、List转数组

以此集合为例进行说明

        List<String> list=new ArrayList();
        list.add("123");
        list.add("abc");
        list.add("456");
        String[] array = new String[list.size()];

1. 方式一、使用for循环得到数组

        for(int i = 0; i < list.size();i++){
            array[i] = list.get(i);
        }
        System.out.println(Arrays.toString(array));

2. 方式二、使用带参的toArray()方法

        list.toArray(array);//
        System.out.println(Arrays.toString(array));

3. 方式三、使用stream流

        array= (String[]) list.stream().toArray();
补充一点:使用无参数toArray()方法
        array=(String[])list.toArray();
        System.out.println(Arrays.toString(array));//抛出ClassCastException异常

  使用无参方法返回的是Object类型的,在java中子类的引用不能指向父类或其它子类对象,就算强转也会导致运行失败并抛出ClassCastException;
源码public Object[] toArray() { return Arrays.copyOf(elementData, size); }
  如果使用该方法我们可以通过循环的方式将Object类型的数组复制给String类型的数组

        Object[] element = list.toArray();
        System.out.println(Arrays.toString(element));//输出[123, abc, def]


        for (int i = 0; i < element.length; i++) {
            array[i] = (String) element[i];
        }
        System.out.println(Arrays.toString(array));//输出[123, abc, def]

完结。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将数组转换为列表,可以使用Arrays类的asList方法。这个方法接受一个数组作为参数,并返回一个固定大小的列表。你可以通过这个列表来访问和操作数组的元素。但需要注意的是,asList返回的列表不支持添加或删除元素的操作。 下面是将数组转换为列表的示例代码: String[] strs = {"1","5","3"}; List<String> strList = Arrays.asList(strs); 当你使用asList方法将数组转换为列表后,你可以像操作常规的列表一样访问和操作元素。例如,你可以使用get方法获取列表中的元素,使用set方法修改特定位置的元素,使用subList方法获取指定范围内的子列表等等。 然而,需要注意的是,由于asList返回的列表是一个固定大小的列表,你不能对其进行添加或删除元素的操作。如果你试图进行这样的操作,会抛出UnsupportedOperationException异常。 如果你需要在数组转换为列表后进行添加或删除元素的操作,你可以创建一个新的ArrayList并将asList返回的列表作为构造函数的参数传入。这样做可以得到一个长度可变的列表,可以进行添加或删除元素的操作。 下面是使用ArrayList来将数组转换为列表的示例代码: String[] strs = {"1","5","3"}; List<String> strList = new ArrayList<>(Arrays.asList(strs)); 通过这种方式,你就可以将数组转换为一个长度可变的列表,并可以灵活地对列表进行添加或删除元素的操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值