黑马程序员技术交流社区

标题: 数组 转list的问题 [打印本页]

作者: 沈雷    时间: 2011-8-5 14:14
标题: 数组 转list的问题
[code=java]public class Core {
   
    public static void main(String[] args){
        String[] strs = new String[10];
        strs[0] = ";";
        List<String> list = Arrays.asList(strs);
        for(String str:list){
            if(str.equals(";")){
                list.remove(str);//有错误
            }
        }
        
    }
}[/code]
为什么执行到list.remove(str)就出现:

Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.remove(AbstractList.java:144)
at java.util.AbstractList$Itr.remove(AbstractList.java:360)
at java.util.AbstractCollection.remove(AbstractCollection.java:252)
at com.General.Core.main(Core.java:16)

2. 如果我想将String[] strs转成 ArrayList<String>,该怎么办?
作者: 匿名    时间: 2011-8-5 16:51
下面是我看到的一个文章里面的,估计对你有帮助:
我们先看一段代码:
List list1 = new ArrayList();
  list1.add("test");
  
  String[] array = new String[2];
  List list2 = Arrays.asList(array);
array[0] = "test2";
System.out.println(list2.get(0));
list2.add("test");//抛出异常
在执行到l2.add("test")时抛出如下异常:

test2
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:151)
at java.util.AbstractList.add(AbstractList.java:89)
at TesException.main(TesException.java:20)

为什么会这样呢?

解释如下:

上面代码中list1是用正常方式下创建的List,可以增删内容

而list2是一个固定大小的List,不可以对其进行进行修改操作,对array的任何操作,若想修改list2的内容,只能通过修改其对应的array,从上面这一点也是可以看出的(关于这些解释可以参看api文档)。那么为什么会这样呢,其实List结构按是否可修改也是可以在分为两个类型的,但是collection框架已经有太多的接口类型了,若在对每种接口类型都分出一个unmodifiable类型的接口,那么最后collection框架会更大,对于学习与使用都会需要记住更多的接口。所以我想这样做的关键一点是:统一接口,减少开发人员的负担。但是若文档中没有对这一点说清楚,有些喜欢刨根问题的程序员会很郁闷。

我猜测Arrays.asList返回的List内容是Array的内容引用。若可以在List中修改,那么怎么同步呢?因为它们有一个本质的区别Array不能自动增大,若允许在List随便增大,则与其相应的Array的内容怎么保证不可修改呢?他们之间有一个阻抗。最后权衡一下,只能让Arrays.asList返回的List不可修改,或者让返回的List与Array之间没有关系,若这样的话,对于那些很大数组来说性能上就会很有影响。
作者: 匿名    时间: 2011-8-5 18:17
手机看不到代码,遇到这种搞不清的问题,二话把异常往chm文档一扔,看看原因再说
作者: 匿名    时间: 2011-8-5 20:14
字符串数组和list之间的相互转换[code]String str[] = list.toArray(new String[]{});               
List   list= java.util.Arrays.asList(String str[]);[/code]
作者: 詹季春    时间: 2011-8-6 00:10
看了下Array.asList的源代码,源代码如下:[code=java]public static <T> List<T> asList(T... a) {
      return new ArrayList<T>(a);
}[/code]这里的ArrayList并不是java.util.ArrayList,而是Array.java的一个内部类,它只不过是需要转换数组的引用而已[code=java]private static class ArrayList<E> extends AbstractList<E> implements RandomAccess,java.io.Serializable
      //AbstractList实现了List接口,该类中也的确有add和remove方法,但打开一看出乎意料
      public boolean add(E e) {
            add(size(), e);
            return true;
     }
      /**
      * {@inheritDoc}
      *
      * <p>This implementation always throws an
      * {@code UnsupportedOperationException}.
      *
      * @throws UnsupportedOperationException {@inheritDoc}
      * @throws ClassCastException             {@inheritDoc}
      * @throws NullPointerException           {@inheritDoc}
      * @throws IllegalArgumentException       {@inheritDoc}
      * @throws IndexOutOfBoundsException      {@inheritDoc}
      */
     public void add(int index, E element) {
            throw new UnsupportedOperationException();
     }[/code]这个add方法总是跑出异常UnsupportedOperationException,remove方法也是如此。

总结:
在使用Arrays.asList()后调用add,remove这些method时出现java.lang.UnsupportedOperationException异常。

原因:这是由于Arrays.asList() 返回java.util.Arrays$ArrayList, 而不是ArrayList。Arrays$ArrayList和ArrayList都是继承AbstractList,remove,add等method在AbstractList中是默认throw UnsupportedOperationException而且不作任何操作。ArrayList override这些method来对list进行操作,但是Arrays$ArrayList没有override remove(),add()等,所以throw UnsupportedOperationException。  搞了很久,最后才查出来这个问题。
解决办法是使用List lst = new ArrayList()构造一个list,然后通过for循环将值放进lst里面去、还是少用asList
[ 本帖最后由 詹季春 于 2011-08-06  00:11 编辑 ]
作者: 匿名    时间: 2011-8-7 00:30
标题: 回复 板凳 的帖子
呵呵  这个回复 绝对精彩 谢了
作者: 匿名    时间: 2011-8-8 01:31
标题: 回复 8 # 的帖子
你这个回复 真是让我无语了  我没必要粘贴 导入包吧  可是到这里面 它的行数会从新计数  原因就在这了




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2