使用Arrays.asList把数据转换为List的三个坑,看到你就赚到

问题1:

	@Test
    public void Test1(){
        int[] arr1 = {1,2,3};
        Integer[] arr2 = {1,2,3};

        List<int[]> ints = Arrays.asList(arr1); //泛型问int数组
        List<Integer> integers = Arrays.asList(arr2);  //泛型是Integer

        System.out.println(ints);
        //[[I@80169cf] 输出的是数组的地址值,证明它是list里面套的数组
        System.out.println(integers);  
        //[1, 2, 3] 输出的是数组的每个值,证明它是把Integer数组转换成了泛型为Integer的集合
    }

原因:只能是把 int 装箱为 Integer,不可能把 int 数组装箱为 Integer 数组。我们知道,Arrays.asList 方法传入的是一个泛型 T 类型可变参数,最终 int 数组整体作为了一个对象成为了泛型类型 T

解决1:

1.使用Integer数组不使用int数组(上面一句演示Integer数组了,这里不再演示)
2.使用jdk1.8以后方式解决,使用 Arrays.stream 方法来转换,如下代码:

	@Test
    public void Test0(){
        int[] arr1 = {1,2,3};
        //使用jdk8的新特性进行转换
        List ints = Arrays.stream(arr1).boxed().collect(Collectors.toList());
        System.out.println(ints);  //[1, 2, 3]
        System.out.println(ints.size()); //3
        System.out.println(ints.get(0).getClass()); //class java.lang.Integer
    }

可以看到第一个坑是,不能直接使用 Arrays.asList 来转换基本类型数组。

问题2:

转换后的list能否正常使用

	@Test
    public void Test2(){
        Integer[] arr2 = {1,2,3};
        List<Integer> integers = Arrays.asList(arr2);  //泛型是Integer
        integers.add(1); //java.lang.UnsupportedOperationException
    }

在这里插入图片描述
兴许到这你会说,我都已经把数组转换成list了,为什么不能添加元素呢?点进Arrays.asList源码
我们会发现,使用Arrays.asList将数组转换成ArrayList所new的并不是我们平常的ArrayList类,而是Arrays类中的一个静态内部类,而且该内部类虽然是ArrayList但是它不支持增删操作,因为它没有重写父类中的add等方法,所以在调用add方法的时候会去找父类的add,父类的add就会抛异常。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

问题3:

	@Test
    public void Test3(){
        Integer[] arr2 = {1,2,3};
        List<Integer> integers = Arrays.asList(arr2);  //泛型是Integer

        arr2[0] = 6; //修改数组
        integers.set(1,8); //修改集合
        System.out.println(Arrays.toString(arr2));  //[6, 8, 3] 
        System.out.println(integers);   //[6, 8, 3]
        /*
        原始数组:[1,2,3]
        修改后数组:[6, 8, 3] 
        修改后集合:[6, 8, 3] 
         */
    }

我们可以发现,修改数组或集合,都会对二者产生影响,这并不是我们想要的,产生这种bug的原因是什么呢?
看一下 ArrayList 的实现,可以发现 ArrayList 其实是直接使用了原始的数组,新的 List 持有了原始数据的引用,可能会导致原始数据也无法 GC 的问题,最终导致 OOM。
在这里插入图片描述

解决2和3:

问题2:数组使用Arrays.asList转换成list集合后不能使用其增删等方法,而且长度不可改变。
问题3:相互修改产生Bug;
解决思路很简单,我们在new一个List集合即可,把转换的集合数据传进去。

	@Test
    public void Test4(){
        Integer[] arr2 = {1,2,3};
        List<Integer> integers = Arrays.asList(arr2);  //泛型是Integer
        ArrayList<Integer> list = new ArrayList<>(integers); //传入上一个集合的元素
        arr2[0] = 6; //修改数组
        integers.set(1,8); //修改集合
        list.set(2,9); //修改新集合
        System.out.println(Arrays.toString(arr2));  //[6, 8, 3]
        System.out.println(integers);   //[6, 8, 3]
        System.out.println(list);   //[1, 2, 9] 
        /*
            我们新new的list没有受到数组和使用Arrays.asList转换的集合修改的影响,
            因为这个list是我们新new的,它们不在同一个内存空间中,相互不影响
         */
         
		list.add(5);
        System.out.println(list); //[1, 2, 9, 5]
    }

可以看到我们新的list是没有问题的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值