java-一道关于arrays.aslist的题目(代码片段)

yulinlewis yulinlewis     2022-12-05     211

关键词:

题目

有这样一道有趣的题目:

final int[] test = new int[]1,2,3,4;
final Integer[] test2 = new Integer[]1,2,3,4;
final List list1 = Arrays.asList(test);
final List list2 = Arrays.asList(test2);
final List list3 = Arrays.asList(1,2,3,4);
System.out.println(list1.size());
System.out.println(list2.size());
System.out.println(list3.size());

对于上边的3个size(),输出的结果如下:

1
4
4

这道题考察的是Arrays.asList()这个api以及泛型的知识点,工作时用到该api的情景也挺多的。下面分析下,为什么是这个答案。

分析

对于list1,为什么size是1?
这是因为Arrays.asList如果传入的数组是基础数据类型的数组时,会将整个数组作为一个对象来构建ArrayList,所以size是1。在源码实现中:

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

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

可以看到,Arrays.asList的形参是可变参数T... a,等同于一个数组参数T[]。这里的T是泛型。在调用该api时,会直接用传入的参数来构建一个ArrayList。

这个ArrayList<E>是Arrays的静态内部类,同样使用了泛型,而泛型是不支持基础数据类型的。

当传入的参数是一个基础数据类型的数组时,就把整个数组对象解析为泛型T;如果传入的参数是一个对象类型的数组,就把数组中的对象类型解析为泛型T。如下:

传入的参数是int[]时:
int[] -> T[]中的T,此时Arrays.asList()返回的是一个size为1的ArrayList<int[]>


传入的参数是Integer[]时:
Integer[] -> T[],此时Arrays.asList()返回的是一个ArrayList<Integer>,其size的值与Integer[]的length一样

因此,题目里的list1和list2的size会不一样。那为什么直接传入1,2,3,4这四个int参数所得到的结果又是4呢?

这是因为当直接传入参数为基础数据类型时,由于方法形参是泛型数组,于是就通过自动装箱把基础数据类型的参数包装为对应的包装类。比如传入的是int,就自动装箱成Integer,这样就能被泛型所接收了。

也就是说,虽然传入参数是1,2,3,4,其实会通过自动装箱变成一个Integer[]参数,然后传递给T[],最后返回的就是一个ArrayList<Integer>

下面是一个可以证明该过程的例子:

public static void main(final String[] args) 
    final int[] array1 = new int[]1,2,3,4;
    final Integer[] array2 = new Integer[]1,2,3,4;

    test(array1);
    test(array2);
    test(1,2,3,4);


public static <T> void test(final T... a) 
    System.out.println(a.length);

其结果如下:

1
4
4

Arrays.asList的其他知识点

由于Arrays.asList返回的是Arrays的静态内部类ArrayList,这个ArrayList并没有重写add和remove方法的。也就是说,这个ArrayList一旦new出来了,其大小就固定下来了,不能再调用add或者remove方法了,否则就会报错如下:

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

虽然不能调用add或者remove,但可以调用set、contains、sort等其他的方法,也可以进行遍历。

如果我们确实需要调用add或者remove方法,可以有以下方法:

方法一

遍历Arrays.asList返回的集合,然后一个个添加到我们常用的集合里,比如java.util.ArrayList

方法二

使用list.addAll(Arrays.asList(a)),直接把Arrays.asList返回的集合给整个添加到新的集合里。

方法三

可以直接通过new ArrayList<>(Arrays.asList(a))的方法来构建一个有着完善功能的集合。

方法四

使用Collections.addAll()来替代Arrays.asList(),这样得到的就是一个有着完善功能的集合。

泛型(Generics)的知识点

泛型的定义:在程序中我们将一个对象放入集合中,但是集合不会记住对象的类型,当我们在次使用对象的时候,对象变为Object类型,而程序中还是原来的类型,我们必须要自己转换其类型,为了解决这个问题,则提出泛型。

泛型要求包容的是对象类型,而八种基础数据类型不属于对象类型,但是它们有对应的封装类/包装类。并且在调用函数时,会根据参数类型来进行自动装箱或者自动拆箱(Autoboxing and unboxing)。对自动装箱/拆箱有兴趣的可以参考下边的链接。

参考链接

关于不可变列表(由 Arrays.asList() 创建)

】关于不可变列表(由Arrays.asList()创建)【英文标题】:RegardingimmutableList(createdbyArrays.asList())【发布时间】:2014-10-1608:04:28【问题描述】:当我们使用java.util.Arrays.asList()从数组创建列表时,列表是不可变的。我只是想知道当List... 查看详情

关于 Java 接口和多态性

】关于Java接口和多态性【英文标题】:AbouttheJavainterfaceandpolymorphism【发布时间】:2013-04-0714:24:39【问题描述】:我在阅读Java文档时遇到了一个奇怪的案例。这是关于Arrays.asList方法的Oracle的java文档的链接,http://docs.oracle.com/javase... 查看详情

c++ 中的类 Java Arrays.asList()

】c++中的类JavaArrays.asList()【英文标题】:Java-likeArrays.asList()inc++【发布时间】:2013-04-0818:03:51【问题描述】:C++是否支持STL或是否存在支持Arrays.asList()的外部库?典型用法privateArrayList<String>lexeme=newArrayList<String>(Arrays.asLi... 查看详情

arrays类--arrays.aslist()方法使用

java.util类Arraysjava.lang.Object——java.util.ArrayspublicclassArraysextendsObject此类包含用来操作数组(比如排序和搜索)的各种方法。此类还包含一个允许将数组作为列表来查看的静态工厂。除非特别注明,否则如果指定数组引用为null,则... 查看详情

java之arrays.aslist陷阱

Java.Util.Arrays可以将数组转换为List,具体的定义如下:@SafeVarargspublicstatic<T>List<T>asList(T...a){returnnewArrayList<>(a);}可以看到实际上是将这个数组转换成为了ArrayList<>,看似没有问题,但是当我们使用add和remove的时候... 查看详情

java中的arrays的aslist的坑(代码片段)

错误案例packagecom;importjava.util.Arrays;importjava.util.List;publicclassArrayAsListTestpublicstaticvoidmain(String[]args)String[]arr=newString[]"a","b","c";List<String>arrayList=Arrays.asList(arr);arrayList.add("d");错误原理此ArrayList非彼Ar... 查看详情

arrays.aslist方法遇到的问题

在使用Arrays.asList(T...a)方法时,遇到了java.lang.UnsupportedOperationException 异常。 后来发现,该方法返回的类型是Arrays$ArrayList,即Arrays类的内部类ArrayList,而非集合中的ArrayList。Arrays$ArrayList继承了AbstractList但没有重写remove... 查看详情

javaarrays.aslist

List<String>list=Arrays.asList("ABCDEFGHIJKL".split(""));1.java中Arrays.asList生成的集合是属于Arrays中内部类,这个内部类不支持各种 removeAll retainAll操作,会抛出java.lang.UnsupportedOperationException异常.因为Arrays.a 查看详情

coding++:arrays.aslist()-java.lang.unsupportedoperationexception异常处理

这个异常遇到了才知道坑这么大,坑爹的方法。privateString[]otherUserFromArray=newString[]{“3”,“4”,“发放”};List<String>userFromList=Arrays.asList(otherUserFromArray);在使用Arrays.asList() 查看详情

为啥 Arrays.asList() 返回自己的 ArrayList 实现

】为啥Arrays.asList()返回自己的ArrayList实现【英文标题】:WhydoesArrays.asList()returnitsownArrayListimplementation为什么Arrays.asList()返回自己的ArrayList实现【发布时间】:2011-06-0705:30:30【问题描述】:我最近发现在Java中实际上有2种不同的Arra... 查看详情

使用arrays.aslist抛出java.lang.unsupportedoperationexception

...icclassListTest{publicstaticvoidmain(String[]args){List<Integer>list=Arrays.asLi 查看详情

arrays.aslist()用法梳理(代码片段)

Arrays.asList()用法梳理asList概述Arrays是java容器相关操作的工具类,asList方法将Array转换为list,是Array和List之间的桥梁。asList本质使用工具类Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的add/remove/clear方法... 查看详情

arrays.aslist()不可添加或删除元素的原因

...va中奖数组转换为List<T>容器有一个很方便的方法 Arrays.asList(T...a),我通过此方法给容器进行了赋值操作,接着对其进行添加元素,却发现会抛出一个(java.lang.UnsupportedOperationException)异常。看了一下源码:publicstatic<T&g... 查看详情

arrays.aslist()(代码片段)

Arrays.asList()将一个数组转化为一个List对象,这个方法会返回一个ArrayList类型的对象。@SafeVarargs@SuppressWarnings("varargs")publicstatic<T>List<T>asList(T...a)returnnewArrayList<>(a);这个ArrayList类并非java.util.A 查看详情

arrays.aslist中所遇到的坑

...supportedOperationException异常从代码定位来看,原来是使用了Arrays.asList()方法时把一个数组转化成List列表时,对得到的List列表进行add()和remove()操作,所以导致了这个问题。 对于这个问题,现在来总结下,当然会总结Arrays下面的... 查看详情

从arrays.aslist到collection.toarray()(代码片段)

Arrays.asList()简介Arrays.asList()在平时开发中还是比较常见的,我们可以使用它将一个数组转换为一个List集合。String[]myArray="Apple","Banana","Orange";List<String>myList=Arrays.asList(myArray);//上面两个语句等价于... 查看详情

数组的 Arrays.asList()

】数组的Arrays.asList()【英文标题】:Arrays.asList()ofanarray【发布时间】:2010-11-1722:31:39【问题描述】:这个转换有什么问题?publicintgetTheNumber(int[]factors)ArrayList<Integer>f=newArrayList(Arrays.asList(factors));Collections.sort(f);returnf.ge 查看详情

转换 Arrays.asList 导致异常:java.util.Arrays$ArrayList 无法转换为 java.util.ArrayList

】转换Arrays.asList导致异常:java.util.Arrays$ArrayList无法转换为java.util.ArrayList【英文标题】:castingArrays.asListcausingexception:java.util.Arrays$ArrayListcannotbecasttojava.util.ArrayList【发布时间】:2011-10-0205:32:18【问题描述】:我是Java新手,我想... 查看详情