Arrays.asList 为什么不能 add 或者 remove 而 ArrayList 可以

分析如下例子:

 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/

时间: 2024-10-06 00:38:59

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

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

在平时的开发过程中,我们知道可以将一个Array的对象转化为List.这样的操作,我们只要采用Arrays.asList这个方法就行了.笔者前段时间一直用这个方法,有一天,我发现通过Arrays.asList得到的List无法进行add和remove等操作. 下面是一段很简单的测试代码: public class MainFacade { public static void main(String[] args) { List<Integer> list = Arrays.asList(1,

java使用Arrays.asList快速创建List集合

程序中某段案例代码如下: Map<String, List<CronTrigger>> tMap = new HashMap<String, List<CronTrigger>>(); tMap.put(name, Arrays.asList(new CronTrigger[] { trigger })); 程序运行抛出异常:java.lang.UnsupportedOperationException 错误原因: 为了快速创建List而使用了Arrays.

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

在项目中对List进行操作时报错java.lang.UnsupportedOperationException,后来发现操作的List是由数组转换而成的,通过看源码发现问题,并写测试程序如下. 代码块: public class ListTest { public static void main(String[] args) { String[] array = {"1","2","3","4","5"}

Arrays.asList中所遇到的坑

前言 最近在项目上线的时候发现一个问题,从后台报错日志看:java.lang.UnsupportedOperationException异常 从代码定位来看,原来是使用了Arrays.asList()方法时把一个数组转化成List列表时,对得到的List列表进行add()和remove()操作, 所以导致了这个问题. 对于这个问题,现在来总结下,当然会总结Arrays下面的一些坑. 源代码分析 首先,遇到问题不可怕,遇到问题解决就是了,但是必须要保证下次不会再犯相同的问题. Arrays.asL

Arrays.asList使用误区

Arrays.asList使用的jar包是import java.util.Arrays;   Arrays.asList是使用该jar中的ArrayList方法 1.  基本类型数组 Int [] intArr={1,2,3}; List listArr=Arrays.asList(intArr); System.out.println(listArr.size());  ///长度为1 总结:Arrays.ArrayList的参数为可变长泛型,而基本类型(int.boolean.char等)

Arrays.asList()的踩坑

用迭代器实现删除集合元素的时候,遇到了一个问题 1 public static void main(String[] args) { 2 String[] ss = {"sys","admin","visa","bude"}; 3 List<String> list = Arrays.asList(ss); 4 9 Iterator it = list.iterator(); 10 while(it.hasNext

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

这个异常遇到了才知道坑这么大,坑爹的方法. private String[] otherUserFromArray = new String[]{“3”, “4”, “发放”}; List<String> userFromList = Arrays.asList(otherUserFromArray); 在使用 Arrays.asList()转化数组成为list的时候,生成了ArrayList, 表面上看是 java.util.ArrayList, 实际上是Arrays的内部类 ArrayLi

Java-Arrays类-Arrays.asList()方法详解

此类包含用来操作数组(比如排序和搜索)的各种方法.此类还包含一个允许将数组作为列表来查看的静态工厂. Arrays.asList() 是将数组作为列表来查看的方法,值得注意的是: public class Test { public static void main(String[] args) { int[] a = new int[]{1,2,3,4,5,6,7,8}; List list1 = Arrays.asList(a); System.out.println(list1.size(

Arrays.asList 返回值类型

public static void main(String[] args) { Integer[] datas = {1,2,3,4,5}; List<Integer> list = Arrays.asList(datas); list.add(5); System.out.println(list.size()); } 该代码会报错    java.lang.UnsupportedOperationException  ---不支持的操作 那么为什么不支持呢,先看API 再看源码就能很明白