浅谈Arrays.asList()方法

一.引言:
实际操作中,我们会遇到需要将数组转化为list的情况,这个时候我们可以借助Java的Arrays类的方法进行便捷操作,接下来来看以下操作的例子:

Integer[] arr= {1, 2, 3};//1
List<Integer> list = new ArrayList<>(Arrays.asList(arr));//2
list.add(4);
System.out.println(list.toString());

结果如下:

[1, 2, 3, 4]

接下来让我们来看下经常出现的两种方式的情况。

二.定义数组的类型为包装类型或者是基本类型?

我们来看下面一个例子:

int[] arr1= {1, 2, 3};
Integer[] arr2 = {1, 2, 3};
List<int[]> list1 = new ArrayList<>(Arrays.asList(arr1));
List<Integer> list2 = new ArrayList<>(Arrays.asList(arr2));
System.out.println("基本类型转化后的集合大小为:"+list1.size()+
         "\n包装类型转化后的集合大小为:"+list2.size());

输出结果为:

基本类型转化后的集合大小为:1
包装类型转化后的集合大小为:3

分析:
我们看一下asList()方法,

public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }

可以看到他的参数为T,我们来简单普及下java泛型T,泛型T本质是Object类型 ,是引用类型 ,不包括基本类型,int这种基本类型不是。我们知道任何类型的对象都有一个 class 属性,这个属性代表了这个类型本身。原生数据类型,比如 int,short,long等,是没有这个属性的,具有 class 属性的是它们所对应的包装类 Integer,Short,Long。
  因此,这个错误产生的原因可解释为:asList 方法的参数必须是对象或者对象数组,而原生数据类型不是对象——这也正是包装类出现的一个主要原因。当传入一个原生数据类型数组时,asList 的真正得到的参数就不是数组中的元素,而是数组对象本身!此时List 的唯一元素就是这个数组。
  ps:从两个数组转化为list,IDEA自动生成的实例化对象也可以观察到,Integer是List,而int的是List<int[]>,因此包装类型的list还是包装类型,而基本类型的list是放入了他对应的数组。

三. 该如何修改list的大小

我们来看下面一个例子:

 Integer[] arr1= {1, 2, 3};
 List<Integer> list1 = Arrays.asList(arr1);
  list1.add(4);
  System.out.println(list1);

输出结果为:

Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.AbstractList.add(AbstractList.java:148)
	at java.util.AbstractList.add(AbstractList.java:108)
	at com.test.main(test.java:17)

我们查看asList方法的描述,出现一句:

Returns a fixed-size list backed by the specified array.

意思是:返回由指定数组支持的固定大小列表

接着查看asList方法调用的ArrayList()方法:

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);
    }

    @Override
    public int size() {
        return a.length;
    }

    //...
}

分析:
直接使用asList()生成的list固定了集合的大小,不能实现add,remove等操作。
原因在于asList调用了一个静态表内部类ArrayList,在这个内部类中有一个被声明为 final 的数组 a ,所有传入的元素都会被保存在这个数组 a 中。到此,谜底又揭晓了: asList 方法返回的确实是一个 ArrayList ,但这个 ArrayList 并不是 java.util.ArrayList ,而是 java.util.Arrays 的一个内部类。这个内部类用一个 final 数组来保存元素,因此用 asList 方法产生的 ArrayList 是不可修改大小的。
因此需要创建一个真正的List,
List list = new ArrayList<>(Arrays.asList(arr)),
在上面这段代码中,我们 new 了一个 java.util.ArrayList ,然后再把 asList 方法的返回值作为构造器的参数传入,最后得到的 myList 自然就是可以动态扩容的了。

四.总结

  1. asList()适用于将数组转化为list的一个工具类;
  2. asList()转化为数组最好是包装类型或者是引用类型的;
  3. asList()转化为数组时,最好创建一个真正的ArrayList,方便后续的add,remove等操作。
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值