Java Arrays.AsList原理及用法实例

java.util.Arrays的asList方法可以方便的将数组转化为集合,我们平时开发在初始化ArrayList时使用的比较多,可以简化代码,但这个静态方法asList()有几个坑需要注意:

一. 如果对集合使用增加或删除元素的操作将会报错

如下代码:

List list = Arrays.asList("a","b","c");

list.add("d");

输出结果:

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

Arrays.asList的源码虽然返回的是一个ArrayList,但这个ArrayList是Arrays内部的一个静态类(java.util.Arrays.ArrayList),并不是我们平时用的java.util.ArrayList只是名字一样,包名不一样:

这个ArrayList也继承自AbstractList,但是却没有实现add(),remove()方法用这两个方法其实调用的是AbstractList的默认方法:

public void add(int index, E element) {
  throw new UnsupportedOperationException();
}

直接抛出" UnsupportedOperationException"的异常!

所以当我们调用这个ArrayList的add方法时其实是调用了抽象集合类里的add方法,就抛出了上面的异常,原因是数组虽然提供了转集合的方法, 但本质上还是个数组,数组的长度是固定的,所以jdk的作者没有实现add()和remove()方法。

大家在使用的时候需要注意,要结合具体业务场景判断:如果只是对转成后的集合进行遍历或使用stream()流操作都没有问题,可以正常使用(修改元素也没问题) 但如果需要新增元素或删除元素等改变集合长度的操作就要避免,否则报错就会影响到我们正常的业务逻辑。

二. 长度问题

还是Arrays的asList(),该方法无法将一个基本类型的数组转换成集合List,或者说基本类型虽然能转换成功,但不是"我们想要的集合",因为asList方法接收的是一个泛型的变长参数。

而基本数据类型是无法被泛型化的,这样的话对于泛型而言,基本数据类型会被作为一个"[x"的类型,"["表示这是一个数组,"x"为当前数组的类型,例如: int[] 实际上它的类型是"[I"

这样的话Arrays.asList传入的参数是基本类型的话,会把数组当做一个元素处理(长度=1),如果我们要遍历List或获取List的长度就不准确了,类似下面的用法:

int array[] = {1,2,3,4,5};
List list = Arrays.asList(array);
System.out.println("长度="+list.size());
System.out.println("是否含有元素3="+list.contains(3));

输出结果:

长度=1是否含有元素3=false

如果我们的代码里用到了这样获取长度或判断是否包含指定元素的操作就要注意写法,否则就会影响我们的逻辑流程!

为避免这样的问题出现,有很多种其他写法,比如将array转成包装类(即引用类型),如下:

Integer array[] = {1,2,3,4,5};
List list = Arrays.asList(array);
System.out.println("长度="+list.size());
System.out.println("是否含有元素3="+list.contains(3));

输出结果:

长度=5是否含有元素3=true

当然也可以使用google的集合类"Ints.asList",如下:

int array[] = {1,2,3,4,5};
List list = Ints.asList(array);
System.out.println("长度="+list.size());
System.out.println("是否含有元素3="+list.contains(3));

输出结果:

长度=5是否含有元素3=true

但是google的Ints.asList方法返回的list也是一个自己实现的集合,同样不支持add和remove方法,如果既要保证转换成list后的数据长度正确又要能增删操作的话,就用java.util.ArrayList吧。

三. Arrays.asList方法返回的是数组的一个视图,也就是说对这个list的操作都会反映在原数组上

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • java 源码分析Arrays.asList方法详解

    最近,抽空把java Arrays 工具类的asList 方法做了源码分析,在网上整理了相关资料,记录下来,希望也能帮助读者! Arrays工具类提供了一个方法asList, 使用该方法可以将一个变长参数或者数组转换成List . 其源代码如下: /** * Returns a fixed-size list backed by the specified array. (Changes to * the returned list "write through" to the arr

  • Java用Arrays.asList初始化ArrayList实例方法

    Java中使用Arrays.asList初始化ArrayList package xiaoling; import java.util.Arrays; import java.util.ArrayList; import java.util.List; public class ListTest{ public static void main(String[] args){ List<List<Integer>> list = new ArrayList<>(); f

  • Java中Arrays.asList()方法详解及实例

    Arrays.asList() 是将数组作为列表. 问题来源于: public class Test { public static void main(String[] args) { int[] a = {1, 2, 3, 4}; List list = Arrays.asList(a); System.out.println(list.size()); //1 } } 期望的输出是 list 里面也有4个元素,也就是 size 为4,然而结果是1. 原因如下: 在 Arrays.asLis

  • Java Arrays.asList使用方法解析

    Arrays.asList()方法的作用是将数组或一些元素转为集合,而你得到的集合并不是我们通常使用的List集合,而是Arrays里面的一个内部类.阿里的开发手册上java开发规范说到使用工具类Arrays.asList()方法把数组转换成集合时,不能使用其修改集合相关的方法,它的add/remove/clear方法会抛出java.lang.UnsupportedOperationException的异常. 一.Arrays.asList的方法说明 public static void mai

  • 千万别这样使用Arrays.asList详解

    前言 使用Arrays.asList()的原因无非是想将数组或一些元素转为集合,而你得到的集合并不一定是你想要的那个集合. 而一开始asList的设计时用于打印数组而设计的,但jdk1.5开始,有了另一个比较更方便的打印函数Arrays.toString(),于是打印不再使用asList(),而asList()恰巧可用于将数组转为集合. 1.错误用法 如果你这样使用过,那你可要注意了. 错误一 将基本类型数组作为asList的参数 int[] arr = {1,2,3}; List list =

  • Java踩坑记录之Arrays.AsList

    前言 java.util.Arrays的asList方法可以方便的将数组转化为集合,我们平时开发在初始化ArrayList时使用的比较多,可以简化代码,但这个静态方法asList()有几个坑需要注意: 一. 如果对集合使用增加或删除元素的操作将会报错 如下代码: List list = Arrays.asList("a","b","c"); list.add("d"); 输出结果: Exception in thread &q

  • Arrays.asList方法总结

    话不多说,请看代码: import java.util.Arrays; import java.util.List; /** * * 本类演示了Arrays类中的asList方法 * 通过四个段落来演示,体现出了该方法的相关特性. * * (1) 该方法对于基本数据类型的数组支持并不好,当数组是基本数据类型时不建议使用 * (2) 当使用asList()方法时,数组就和列表链接在一起了. * 当更新其中之一时,另一个将自动获得更新. * 注意:仅仅针对对象数组类型,基本数据类型数组不具备该特性

  • 浅谈Arrays.asList() 和ArrayList类型区别

    <pre name="code" class="html"><pre name="code" class="html">Arrays.asList() 将一个数组转化为一个List对象,这个方法会返回一个ArrayList类型的对象, 这个ArrayList类并非java.util.ArrayList类,而是Arrays类的静态内部类!用这个对象对列表进行添加删除更新操作,就会报UnsupportedO

  • 浅谈Arrays.asList()方法的使用

    首先,该方法是将数组转化为list.有以下几点需要注意: (1)该方法不适用于基本数据类型(byte,short,int,long,float,double,boolean) (2)该方法将数组与列表链接起来,当更新其中之一时,另一个自动更新 (3)不支持add和remove方法 上代码: package com.hdu.test; import java.util.Arrays; import java.util.List; abstract public class AsllistTest

  • Java Arrays.AsList原理及用法实例

    java.util.Arrays的asList方法可以方便的将数组转化为集合,我们平时开发在初始化ArrayList时使用的比较多,可以简化代码,但这个静态方法asList()有几个坑需要注意: 一. 如果对集合使用增加或删除元素的操作将会报错 如下代码: List list = Arrays.asList("a","b","c"); list.add("d"); 输出结果: Exception in thread "

  • Java延迟队列原理与用法实例详解

    本文实例讲述了Java延迟队列原理与用法.分享给大家供大家参考,具体如下: 延时队列,第一他是个队列,所以具有对列功能第二就是延时,这就是延时对列,功能也就是将任务放在该延时对列中,只有到了延时时刻才能从该延时对列中获取任务否则获取不到-- 应用场景比较多,比如延时1分钟发短信,延时1分钟再次执行等,下面先看看延时队列demo之后再看延时队列在项目中的使用: 简单的延时队列要有三部分:第一实现了Delayed接口的消息体.第二消费消息的消费者.第三存放消息的延时队列,那下面就来看看延时队列dem

  • Java局部内部类原理与用法实例分析

    本文实例讲述了Java局部内部类原理与用法.分享给大家供大家参考,具体如下: 一 点睛 如果把一个内部类放在方法中定义,那么这个内部类就是一个局部内部类,局部内部类仅在方法里有效. 由于局部内部类不能在外部类的方法以外的地方使用,因此局部内部类也不能使用控制符合static修饰符修饰. 如果需要用局部内部类定义变量.创建实例或派生子类,那么都只能在局部内部类所在的方法中进行. 二 代码 public class LocalInnerClass { public static void main(

  • Java反射技术原理与用法实例分析

    本文实例讲述了Java反射技术原理与用法.分享给大家供大家参考,具体如下: 本文内容: 产生反射技术的需求 反射技术的使用 一个小示例 首发日期:2018-05-10 产生反射技术的需求: 项目完成以后,发现需要增加功能,并且希望增加功能并不需要停止项目运行. 在希望不关停项目运行的情况下,于是考虑到将功能都放到一个单独的项目之外的模块中,每一个功能实现都从这个模块中获取[实际上这个考虑应该是项目开始前就考虑,这个例子可能不是很好].于是就有了反射的产生.(这种思想有点类似工厂模式,如果学过设计

  • Java过滤器模式原理及用法实例

    过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来.这种类型的设计模式属于结构型模式,它结合多个标准来获得单一标准. 实现 我们将创建一个 Person 对象.Criteria 接口和实现了该接口的实体类,来过滤 Person 对象的列表.CriteriaPatternDemo,我们的演示类使用 Criteria 对象,基于各种标准和它们的结合来过滤 Pe

  • Java设计模式之策略模式原理与用法实例详解

    本文实例讲述了Java设计模式之策略模式原理与用法.分享给大家供大家参考,具体如下: 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化.其中JDK里面的TreeSet类和TreeMap类就用到了策略模式.这两个类是带排序的集合类,其中排序的规则就相当于策略模式里定义的一系列算法,而集合类就相当于是策略模式里的环境类,供用户使用,用只知道TreeSet和TreeMap是带排序的,至于怎么排序的,是由排序的算法决定的. 策略模式

  • Java设计模式之装饰模式原理与用法实例详解

    本文实例讲述了Java设计模式之装饰模式原理与用法.分享给大家供大家参考,具体如下: 装饰模式能在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.它是通过创建一个包装对象,也就是装饰来包裹真实的对象.JDK中IO的设计就用到了装饰模式,通过过滤流对节点流进行包装来实现功能的扩展. 装饰模式的角色的组成: ① 抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加工功能的对象.(InputStream.OutputStream) ② 具体构件(Concrete Co

  • Java泛型继承原理与用法详解

    本文实例讲述了Java泛型继承原理与用法.分享给大家供大家参考,具体如下: 一 点睛 当创建了带泛型声明的接口.父类之后,可以为该接口创建实现类,或从该父类来派生子类,但值得指出的是,当使用这些接口.父类时不能再包含类型形参. 如果使用泛型类时没有传入实际的类型参数,Java编译器可能发出警告:使用了未经检查或不安全的操作--这就是泛型检查的警告. 二 实战--传入实际的类型参数 public class A1 extends Apple<String> { // 正确重写了父类的方法,返回值

  • Java 反射机制原理与用法详解

    本文实例讲述了Java 反射机制原理与用法.分享给大家供大家参考,具体如下: 反射反射,程序员的快乐! 1.什么是反射? Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:并且能改变它的属性.而这也是Java被视为动态(或准动态,为啥要说是准动态,因为一般而言的动态语言定义是程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言.从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是

  • Java 的抽象类原理与用法分析

    本文实例讲述了Java 的抽象类原理与用法.分享给大家供大家参考,具体如下: Java 的抽象类 用abstract关键字来修饰一个类时,这个类叫做抽象类: 用abstract来修饰一个方法时,该方法叫做抽象方法. 抽象方法:只有方法的声明,没有方法的实现.以分号结束:abstract int abstractMethod(int a ); 含有抽象方法的类必须被声明为抽象类. 抽象类不能被实例化.抽象类是用来被继承的,抽象类的子类必须重写父类的抽象方法,并提供方法体.若没有重写全部的抽象方法,

随机推荐