分析如下例子:

 1 import java.util.Arrays;
2 import java.util.List;
3
4
5 public class Test {
6 public static void main(String[] args) {
7 Integer[] a = {0,1,2,3,4,5,6};
8 List<Integer> c = Arrays.asList(a);
9 for (Integer integer : c) {
10 System.out.println(integer);
11 }
12 c.add(7);
13 c.remove(0);
14
15 }
16 }

打印结果为:

0
1
2
3
4
5
6
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:151)
at java.util.AbstractList.add(AbstractList.java:89)
at com.cys.collections.MapTest.main(MapTest.java:14)

查看Arrays.asList() 底层实现:

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

实现同样是ArrayList ! But,再向下看:

文件名: Arrays$ArrayList.class 表明ArrayList是一个Arrays 类的内部类,与我们平时使用的ArrayList 并不同;

它继承了一个抽象类AbstractList并使用该抽象类的add 和 remove方法:

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

  全部抛出了一个UnsupportedOperationException 异常,说明该list不支持改变它长度的情况。

但是同样是数组实现的直接  new 的 ArrayList为什么就可以呢?

  让我们看一看它的add 代码:

 1  public boolean add(E o) {
2 ensureCapacity(size + 1); // Increments modCount!!
3 elementData[size++] = o;
4 return true;
5 }
  public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacity(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}

  

这两个方法里面的第一行,均是确信当前容量是否能容下新增加的对象。

public void ensureCapacity(int minCapacity) {
modCount++;
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
int newCapacity = (oldCapacity * 3)/2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
elementData = (E[])new Object[newCapacity];
System.arraycopy(oldData, 0, elementData, 0, size);
}
}

  此方法里,一旦发现容量不足,会自动扩充容量,新的大小是

int newCapacity = (oldCapacity * 3)/2 + 1

再通过拷贝方法,新new一个数组。

  remove 就很简单了,就是单纯的删去一个位置上的数据,然后把后面的数据依次向前挪。

所以 new ArrayList 可以 remove 和add 。

题外话:

我们看到ArrayList 的扩充是原来的1.5倍+1,所以为了避免频繁扩充带来的扩充损耗,应当尽可能大的new ArrayList的初始长度,

但是太大的话,如果数据增长很慢,就会占用很多没用的内存,所以这个长度还是需要根据业务的实际情况,合理申请。

http://www.cnblogs.com/caoyusongnet/

Arrays.asList 为什么不能 add 或者 remove 而 ArrayList 可以的更多相关文章

  1. Arrays.asList()后调用add,remove这些method时出现java.lang.UnsupportedOperationException异常

    String[] queryNames = request.getParameterValues("queryName"); List<String> queryNam ...

  2. 为什么Java里的Arrays.asList不能用add和remove方法?

    在平时的开发过程中,我们知道能够将一个Array的对象转化为List.这种操作,我们仅仅要採用Arrays.asList这种方法即可了.笔者前段时间一直用这种方法,有一天,我发现通过Arrays.as ...

  3. Arrays.asList()注意

    api: public static <T> List<T> asList(T... a) 返回一个受指定数组支持的固定大小的列表.(对返回列表的更改会“直接写”到数组.)此方 ...

  4. 在Arrays.asList()引发的问题中进一步学习集合与泛型等内容

    前言 最近在网上看到一个问题,情况类似如下(记为问题1): public class Demo { public static void main(String[] args) { System.ou ...

  5. java Arrays.asList方法注意事项

    1. 简介 Arrays.asList()方法可以将数组转化为长度固定的列表. 该方法强调了列表的长度是固定的,因此不能使用list的add和remove方法修改list长度. 2. 示例 impor ...

  6. Arrays.asList中所遇到的坑

    前言 最近在项目上线的时候发现一个问题,从后台报错日志看:java.lang.UnsupportedOperationException异常 从代码定位来看,原来是使用了Arrays.asList() ...

  7. 利用Jdk 6260652 Bug解析Arrays.asList

    在java.util.ArrayList源码中: c.toArray might (incorrectly) not return Object[] (see 6260652) 产生疑惑: 附上Jav ...

  8. Arrays.asList引起的java.lang.UnsupportedOperationException解决方法

    在项目中对List进行操作时报错java.lang.UnsupportedOperationException,后来发现操作的List是由数组转换而成的,通过看源码发现问题,并写测试程序如下. 代码块 ...

  9. coding++:Arrays.asList() - java.lang.UnsupportedOperationException异常处理

    这个异常遇到了才知道坑这么大,坑爹的方法. private String[] otherUserFromArray = new String[]{“3”, “4”, “发放”}; List<St ...

随机推荐

  1. dsd

    nodeName属性 nodeName属性规定节点的名称 nodeName是只读的 元素节点的nodeName与属性名相同 属性节点的nodeName与属性名相同 文本节点nodeName始终是#te ...

  2. Oracle官方文档学习路线图

  3. Ajax+jquery+jaso传输数据

    所谓的Ajax.这里我们讲二种方法  方法一:(微软有自带Ajax框架)  在Asp.net里微软有自己的Ajax框架.就是在页面后台.cs文件里引入 using System.Web.Service ...

  4. Spring Aop 梳理

    Aspect Oriented Programming  面向切面编程.解耦是程序员编码开发过程中一直追求的.AOP也是为了解耦所诞生. 具体思想是:定义一个切面,在切面的纵向定义处理方法,处理完成之 ...

  5. zinnia项目功能分析

    Zinnia是基于Django开发的一个开源博客系统,近期为了写一个类博客系统特对它做功能分析,+号的多少表明这个功能对于博客的重要性: ++评论:Comments 站点图:Sitemaps ]压缩视 ...

  6. 建站记录:设置apache .htaccess文件给网站添加404错误处理页面

    有些空间服务商会在后台设置中,提供这个选项,可以直观地设置404错误指向的页面,这一点很方便,比如我之前用的阿里云虚拟主机就可以在控制台直接设置. 新租用的香港主机后台没有找到选取文件的地方,只是可以 ...

  7. vue实现淘宝商品详情页属性选择功能

    方法一是自己想出来的,方法二来自忘记哪里看到的了 不知道是不是你要的效果: 方法一:利用input[type="radio"] css代码: input { display: no ...

  8. Python撸支付宝红包教程,行走在灰色产业边缘的程序员!

      2018年刚到就作死撸羊毛(支付宝).2017年用分享给支付宝好友链接的官方通道"撸"了400大洋. 如许天天早上7:30便起床开愉快心的分享红包链接.200多个老友分享完一次 ...

  9. 关于css盒模型

    在css中,width和height指的是内容区域的宽度和高度.增加内边距,边框和外边距不会影响内容区域的尺寸,但是会增加元素框的总尺寸.假设框的每个边上有10个像素的外边距和5像素的内边距,如果希望 ...

  10. JS 数据类型、赋值、深拷贝和浅拷贝

    js 数据类型 六种 基本数据类型: Boolean. 布尔值,true 和 false. null. 一个表明 null 值的特殊关键字. JavaScript 是大小写敏感的,因此 null 与 ...