集合之asList的缺陷
在实际开发过程中我们经常使用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的缺陷的更多相关文章
- Java提高篇(三六)-----Java集合细节(二):asList的缺陷
在实际开发过程中我们经常使用asList讲数组转换为List,这个方法使用起来非常方便,但是asList方法存在几个缺陷: 一.避免使用基本数据类型数组转换为列表 使用8个基本类型数组转换为列表时会存 ...
- Java 集合细节(二):asList 的缺陷
在实际开发过程中我们经常使用 asList 讲数组转换为 List,这个方法使用起来非常方便,但是 asList 方法存在几个缺陷: 一.避免使用基本数据类型数组转换为列表 使用 8 个基本类型数组转 ...
- 集合之subList的缺陷
我们经常使用subString方法来对String对象进行分割处理,同时我们也可以使用subList.subMap.subSet来对List.Map.Set进行分割处理,但是这个分割存在某些瑕疵. 一 ...
- Java集合详解8:Java集合类细节精讲
今天我们来探索一下Java集合类中的一些技术细节.主要是对一些比较容易被遗漏和误解的知识点做一些讲解和补充.可能不全面,还请谅解. 本文参考:http://cmsblogs.com/?cat=5 具体 ...
- Java集合详解8:Java的集合类细节精讲
Java集合详解8:Java集合类细节精讲 今天我们来探索一下Java集合类中的一些技术细节.主要是对一些比较容易被遗漏和误解的知识点做一些讲解和补充.可能不全面,还请谅解. 本文参考:http:// ...
- Java集合详解8:Java集合类细节精讲,细节决定成败
<Java集合详解系列>是我在完成夯实Java基础篇的系列博客后准备开始写的新系列. 这些文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查 ...
- Java集合概述
容器,是用来装东西的,在Java里,东西就是对象,而装对象并不是把真正的对象放进去,而是指保存对象的引用.要注意对象的引用和对象的关系,下面的例子说明了对象和对象引用的关系. String str = ...
- Java 核心技术-集合-集合框架
说在前面的话: 关于Core Java 集合方面的博文网上已经写烂了,为啥我还要写呢? 答:他们写的都很好,我也学到不少东西,如果把我当做一个系统的话,学习别人.看书.读源码是输入,但是往往形不成一个 ...
- Java 集合 集合与数组之间的转换
Java 集合 集合与数组之间的转换 @author ixenos 数组转集合 Arrays.asList(T... a) 先给结论:用 Arrays.asList(T... a) 将数组转换成集合 ...
随机推荐
- Python import搜索的路径顺序
在程序中导入时,如下顺序 1.Python 标准库模块2.Python 第三方模块3.应用程序自定义模块 import的搜索顺序: 首先判断这个module是不是built-in即内建模块,如果是 ...
- php判断是否isPhone、is_weixin
protected function isPhone(){ $agent = strtolower($_SERVER['HTTP_USER_AGENT']); //pc请求头信息数组 $pc_arr= ...
- C# 如何在Linux操作系统下读取文件
发布在Window环境上的微服务需要部署在Linux环境上,本以为没有什么问题,结果因为一处读取文件路径的原因报错了,在此记录一下两个问题:1.C#如何判断当前运行环境是什么操作系统:2.C#读取文件 ...
- How to download a CRX file from the Chrome web store
如何从 谷歌浏览器商店 离线下载 谷歌浏览器扩展 Simply copying the Chrome store extension url to the following website: htt ...
- PHP自定义函数&数组
<?php//生成随机数 和 时间函数//echo rand();//echo "<br>";//echo rand(0,10);//echo time();// ...
- Arcengine编辑代码
using System; using System.Drawing; using System.Collections; using System.ComponentModel; using Sys ...
- Vue 框架-11-介绍src文件流程及根组件app+HBuilder 配置
Vue 框架-11-介绍src文件流程及根组件app+HBuilder 配置 这是上一篇对目录简单介绍: 关于编辑器,可以使用轻量级的 Sublime Text 3,我使用的是 HBuilder, 但 ...
- 查看组成一个Index的column有哪些
下面是创建一个表,并在上面建立一些index的SQL.我们会新建一个用户,然后再那个schema下运行下面的SQL. create table indtest (f1_num number(10) ...
- <![CDATA[文本内容]]>
DTD中的属性类型 全名:character data 在标记CDATA下,所有的标记.实体引用都被忽略,而被XML处理程序一视同仁地当做字符数据看待, CDATA的形式如下: <[CDATA[ ...
- 使用Axure设计中,大型的后台系统原型总结
使用Axure设计中,大型的后台系统原型总结 2018年4月16日luodonggan 在产品原型设计中,经常会涉及到后台系统原型的设计,如何设计出更规范标准的后台系统原型,是很多产品同行们都会遇到的 ...