前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Arrays.asList使用指南

Arrays.asList使用指南

原创
作者头像
老九学堂-小师弟
修改2019-09-25 18:11:23
6480
修改2019-09-25 18:11:23
举报
文章被收录于专栏:编程语言xuetang编程语言xuetang

一、java.util.Arrays.asList() 的一般用法

  List是一种很有用的数据结构,如果需要将一个数组转换为 List 以便进行更丰富的操作的话,可以这么实现:

  上面这两种形式都是十分常见的:将需要转化的数组作为参数,或者直接把数组元素作为参数,都可以实现转换。

二、极易出现的错误及相应的解决方案

错误一: 将原生数据类型数据的数组作为参数

  前面说过,可以将需要转换的数组作为 asList 方法的参数。假设现在需要转换一个整型数组,那么我们可能会这样写:

  上面这段代码的输出结果是什么,会是3吗?如果有人自然而然地写出上面这段代码的话,那么他也一定会以为 myList 的大小为3。很遗憾,这段代码的输出结果不是3,而是1。如果尝试遍历 myList ,你会发现得到的元素不是1、2、3中的任意一个,而是一个带有 hashCode 的对象。为什么会如此?

  来看一下asList 方法的签名:

  注意:参数类型是 T ,根据官方文档的描述,T 是数组元素的 class。

  如果你对反射技术比较了解的话,那么 class 的含义想必是不言自明。我们知道任何类型的对象都有一个 class 属性,这个属性代表了这个类型本身。原生数据类型,比如 int,short,long等,是没有这个属性的,具有 class 属性的是它们所对应的包装类 Integer,Short,Long。

  因此,这个错误产生的原因可解释为:asList 方法的参数必须是对象或者对象数组,而原生数据类型不是对象——这也正是包装类出现的一个主要原因。当传入一个原生数据类型数组时,asList 的真正得到的参数就不是数组中的元素,而是数组对象本身!此时List 的唯一元素就是这个数组。

解决方案:使用包装类数组

  如果需要将一个整型数组转换为 List,那么就将数组的类型声明为 Integer 而不是 int。

  这时 myList 的大小就是3了,遍历的话就得到1、2、3。这种方案是比较简洁明了的。

  另一种解决方案——他使用了 Java 8 新引入的 API:

错误二:试图修改 List 的大小

  我们知道 List 是可以动态扩容的,因此在创建一个 List 之后最常见的操作就是向其中添加新的元素或是从里面删除已有元素:

  尝试运行这段代码,结果抛出了一个 java.lang.UnsupportedOperationException 异常!这一异常意味着,向 phoneList 添加新元素是不被允许的;如果试图从 phoneList 中删除元素,也会抛出相同的异常。为什么会如此?

  用 asList 方法产生的 List 是固定大小的,这也就意味着任何改变其大小的操作都是不允许的。

  那么新的问题来了:按道理 List 本就支持动态扩容,那为什么偏偏 asList 方法产生的 List 就是固定大小的呢?如果要回答这一问题,就需要查看相关的源码。Java 8 中 asList 方法的源码如下:

  方法中的的确确生成了一个ArrayList ,这不应该是支持动态扩容的吗?别着急,接着往下看。紧跟在 asList 方法后面,有这样一个内部类:

  这个内部类也叫 ArrayList,更重要的是在这个内部类中有一个被声明为 final 的数组 a,所有传入的元素都会被保存在这个数组a中。到此,谜底又揭晓了: asList 方法返回的确实是一个 ArrayList ,但这个 ArrayList 并不是java.util.ArrayList,而是 java.util.Arrays的一个内部类。这个内部类用一个 final 数组来保存元素,因此用 asList 方法产生的 ArrayList是不可修改大小的。

解决方案:创建一个真正的 ArrayList

  既然我们已经知道之所以asList 方法产生的 ArrayList 不能修改大小,是因为这个 ArrayList 并不是“货真价实”的 ArrayList ,那我们就自行创建一个真正的 ArrayList :

  在上面这段代码中,我们 new 了一个 java.util.ArrayList ,然后再把 asList 方法的返回值作为构造器的参数传入,最后得到的 myList 自然就是可以动态扩容的了。

三、用自己的方法实现数组到 List 的转换

  有时,自己实现一个方法要比使用库中的方法好。鉴于 asList 方法有一些限制,那么我们可以用自己的方法来实现数组到 List 的转换:

  这么做自然也是可以达到目的的,但显然有一个缺点:代码相对冗长。

老九学堂会员社群出品

作者:naaman

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档