在实际开发过程中我们经常使用asList讲数组转换为List,这个方法使用起来非常方便,但是asList方法存在几个缺陷:

一、避免使用基本数据类型数组转换为列表

使用8个基本类型数组转换为列表时会存在一个比较有味的缺陷。先看如下程序:

public static void main(String[] args) {
int[] ints = {1,2,3,4,5};
List list = Arrays.asList(ints);
System.out.println("list'size:" + list.size());
}
------------------------------------
outPut:
list'size:1

程序的运行结果并没有像我们预期的那样是5而是逆天的1,这是什么情况?先看源码:

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

asList接受的参数是一个泛型的变长参数,我们知道基本数据类型是无法发型化的,也就是说8个基本类型是无法作为asList的参数的, 要想作为泛型参数就必须使用其所对应的包装类型。但是这个这个实例中为什么没有出错呢?因为该实例是将int 类型的数组当做其参数,而在Java中数组是一个对象,它是可以泛型化的。所以该例子是不会产生错误的。既然例子是将整个int 类型的数组当做泛型参数,那么经过asList转换就只有一个int 的列表了。如下:

public static void main(String[] args) {
int[] ints = {1,2,3,4,5};
List list = Arrays.asList(ints);
System.out.println("list 的类型:" + list.get(0).getClass());
System.out.println("list.get(0) == ints:" + list.get(0).equals(ints));
}
--------------------------------------------
outPut:
list 的类型:class [I
list.get(0) == ints:true

从这个运行结果我们可以充分证明list里面的元素就是int数组。弄清楚这点了,那么修改方法也就一目了然了:将int 改变为Integer。

public static void main(String[] args) {
Integer[] ints = {1,2,3,4,5};
List list = Arrays.asList(ints);
System.out.println("list'size:" + list.size());
System.out.println("list.get(0) 的类型:" + list.get(0).getClass());
System.out.println("list.get(0) == ints[0]:" + list.get(0).equals(ints[0]));
}
----------------------------------------
outPut:
list'size:5
list.get(0) 的类型:class java.lang.Integer
list.get(0) == ints[0]:true

Java细节(2.1):在使用asList时不要将基本数据类型当做参数。

二、asList产生的列表不可操作

对于上面的实例我们再做一个小小的修改:

public static void main(String[] args) {
Integer[] ints = {1,2,3,4,5};
List list = Arrays.asList(ints);
list.add(6);
}

该实例就是讲ints通过asList转换为list 类别,然后再通过add方法加一个元素,这个实例简单的不能再简单了,但是运行结果呢?打出我们所料:

Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(Unknown Source)
at java.util.AbstractList.add(Unknown Source)
at com.chenssy.test.arrayList.AsListTest.main(AsListTest.java:10)

运行结果尽然抛出UnsupportedOperationException异常,该异常表示list不支持add方法。这就让我们郁闷了,list怎么可能不支持add方法呢?难道jdk脑袋堵塞了?我们再看asList的源码:

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

asList接受参数后,直接new 一个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) {
if (array==null)
throw new NullPointerException();
a = array;
}
//.................
}

这是ArrayList的源码,从这里我们可以看出,此ArrayList不是java.util.ArrayList,他是Arrays的内部类。该内部类提供了size、toArray、get、set、indexOf、contains方法,而像add、remove等改变list结果的方法从AbstractList父类继承过来,同时这些方法也比较奇葩,它直接抛出UnsupportedOperationException异常:

public boolean add(E e) {
add(size(), e);
return true;
} public E set(int index, E element) {
throw new UnsupportedOperationException();
} public void add(int index, E element) {
throw new UnsupportedOperationException();
} public E remove(int index) {
throw new UnsupportedOperationException();
}

通过这些代码可以看出asList返回的列表只不过是一个披着list的外衣,它并没有list的基本特性(变长)。该list是一个长度不可变的列表,传入参数的数组有多长,其返回的列表就只能是多长。所以:

Java细节(2.2):不要试图改变asList返回的列表,否则你会自食苦果。

集合之asList的缺陷的更多相关文章

  1. Java提高篇(三六)-----Java集合细节(二):asList的缺陷

    在实际开发过程中我们经常使用asList讲数组转换为List,这个方法使用起来非常方便,但是asList方法存在几个缺陷: 一.避免使用基本数据类型数组转换为列表 使用8个基本类型数组转换为列表时会存 ...

  2. Java 集合细节(二):asList 的缺陷

    在实际开发过程中我们经常使用 asList 讲数组转换为 List,这个方法使用起来非常方便,但是 asList 方法存在几个缺陷: 一.避免使用基本数据类型数组转换为列表 使用 8 个基本类型数组转 ...

  3. 集合之subList的缺陷

    我们经常使用subString方法来对String对象进行分割处理,同时我们也可以使用subList.subMap.subSet来对List.Map.Set进行分割处理,但是这个分割存在某些瑕疵. 一 ...

  4. Java集合详解8:Java集合类细节精讲

    今天我们来探索一下Java集合类中的一些技术细节.主要是对一些比较容易被遗漏和误解的知识点做一些讲解和补充.可能不全面,还请谅解. 本文参考:http://cmsblogs.com/?cat=5 具体 ...

  5. Java集合详解8:Java的集合类细节精讲

    Java集合详解8:Java集合类细节精讲 今天我们来探索一下Java集合类中的一些技术细节.主要是对一些比较容易被遗漏和误解的知识点做一些讲解和补充.可能不全面,还请谅解. 本文参考:http:// ...

  6. Java集合详解8:Java集合类细节精讲,细节决定成败

    <Java集合详解系列>是我在完成夯实Java基础篇的系列博客后准备开始写的新系列. 这些文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查 ...

  7. Java集合概述

    容器,是用来装东西的,在Java里,东西就是对象,而装对象并不是把真正的对象放进去,而是指保存对象的引用.要注意对象的引用和对象的关系,下面的例子说明了对象和对象引用的关系. String str = ...

  8. Java 核心技术-集合-集合框架

    说在前面的话: 关于Core Java 集合方面的博文网上已经写烂了,为啥我还要写呢? 答:他们写的都很好,我也学到不少东西,如果把我当做一个系统的话,学习别人.看书.读源码是输入,但是往往形不成一个 ...

  9. Java 集合 集合与数组之间的转换

    Java 集合 集合与数组之间的转换 @author ixenos 数组转集合 Arrays.asList(T... a) 先给结论:用 Arrays.asList(T... a) 将数组转换成集合 ...

随机推荐

  1. Var与Dynamic的区别

    1.var与dynamic的区别   C#中的很多关键词用法比较容易混淆,var和dynamic就是其中一组,但其实它们是有本质的区别的.var 在编译阶段已经确定类型,在初始化时候,必须提供初始化的 ...

  2. mysql安装配置、主从复制配置详解

    作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/8213723.html 邮箱:moyi@moyib ...

  3. sql按月统计数量和按月累加统计数量

    1.简单的,按月统计数量 SELECT CREATE_DATE, DATE_FORMAT(CREATE_DATE, '%Y-%m') AS month , COUNT(*) AS sum FROM p ...

  4. 【代码笔记】iOS-左右可滑动的选择条

    一,效果图. 二,工程图. 三,代码. RootViewController.h #import <UIKit/UIKit.h> @interface RootViewController ...

  5. 如何发挥ERP系统中的财务监控职能?

    ERP系统的管理理念与特点 ERP,是整合了企业管理理念.业务流程.基础数据.人力物力.计算机硬件和软件于一体的企业资源管理系统.ERP系统运用信息技术将企业的资金流.物资流.信息流进行有效的集成,使 ...

  6. ADB指令大全

    Android Debug Bridge version 1.0.26.26 -a - directs adb to listen on all interfaces for a connection ...

  7. RecyclerView中notifyDataSetChanged刷新总结

    除了adapter.notifyDataSetChanged()这个方法之外,新的Adapter还提供了其他的方法,如下: public final void notifyDataSetChanged ...

  8. Paxos可容错的一致性协议

    一致性问题要求多个process对一个值达成一致.基于消息传递的分布式系统中,在不考虑消息篡改等拜占庭错误的情况下,Paxos可以解决在进程退出,消息延迟,丢失,重复等异常发生的环境中对某个值达成一致 ...

  9. C++发展概述、优缺点及应用领域

    个人观点(C++虽功能强大,但是底层还是调用C,C++为了吸引更多的C程序员,功能过于丰富且复杂,一定程度上反而降低了可编程的实用性.但是不可否认C++ 也是一门艺术.) C++是一门以C为基础发展而 ...

  10. controller断点进入失败:包路径问题

    controller 接受前端参数的方法(前端要有传值给controller的方法,后台要有接收值得方法) 1.@RequestParam 接收表单参数 2.@RequestBody 接收json字符 ...