A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

本帖最后由 大山哥哥 于 2017-1-20 15:09 编辑

         我们在学习集合过程中都学过一个将数组转换为集合的方法,那就是Arrays类里面的asList方法,下面我们用一个案例简单的回顾一下asList方法的用法
import java.util.Arrays;
import java.util.List;
public classDemo3 {
   public static void main(String[] args) {
      //定义String类型的数组
      String[]arr = {"abc","bcd","efg","hij"};
      //通过Arrays类的asList方法 转为List集合
      List<String>list = Arrays.asList(arr);
      //遍历集合
      for (String string : list){
        System.out.println(string);
      }
   }
}
这个方法确实可以将数组转换为集合,但是转成的集合只能做修改元素和查找元素,却不能做任何增加元素或者删除元素的操作,也就是只要改变其长度的操作此集合都不能做,我们用下面的代码去说明一下:



可是,这和我们所知道的集合有冲突阿,我们所知道的普通的List集合是可以做增删的操作的,但是为什么通过asList方法生成的集合却不能做该操作呢?这么做的目的何在呢?
接着来我们就去研究这两个问题
   1:这么做的目的何在?
   2:底层通过什么样的原理来让此集合不能做增删的操作?

首先研究第一个问题:这么做的目的
         我想问大家一个问题,如果我把上面代码中集合的第一个元素修改为“klm”之后,那么被转成集合的那个数组里面的第一个元素改变了没有?我相信很多人都会说“没有”,那么接下来我们去验证一下

通过验证我们知道了,改变集合里面的元素,数组里面的元素也会跟着去改变的,我们得到了一个结论就是数组里面的数据和被转成的集合里面的数据是同一个数据,集合和数组里面的内容是同步改变的,改了数组的数据,那集合的数据也会被改变,改了集合的数据数组的数据也会被改变。然而数组的长度是不能改变的,所以此集合也做了对应的限制。
   我们得到结论,这么做的目的是为了让数组和集合的数据共享
接着研究第二个问题:底层如何做到不能增删
   我们先去观察一下asList方法的源码,

你会发现asList方法返回一个ArrayList集合,但是请大家千万不要被迷惑,此ArrayList可不是咱们日常用的ArrayList集合阿,接下来我们去看一下这个ArrayList的源码


通过观察源码我们发现,需要被转为集合的数组通过ArrayList的构造方法传给ArrayList内部数组类型的a变量,然后无论是get还是set方法都是操作的a数组,所以在我们的测试中我们会看到数组和集合是联动的。但是找了我们发现ArrayList里面并没有增删元素的方法即addremove方法,ArrayList类里面没有但是却能使用addremove方法,那只能说明这两个方法是父类AbstractList的,所以我们去查看AbstractList的源码

原来AbstractList里面的addremove方法里面仅有一句抛出异常的代码,所以当我们用数组转成的集合对象调用addremove方法的时候会报出此异常。但是那为什么其他集合比如LinkedList或者Vector集合调用addremove却不报此异常呢?那是因为LinkedListVector重写了addremove方法,他们的对象使用的是自己的这两个方法,而不是使用的AbstractListaddremove方法。

36 个回复

正序浏览
大山哥哥 发表于 2017-2-9 16:59
不是一个ArrayList类哦, asList方法返回的这个ArrayList对象是个内部类对象

谢谢,看了源码终于知道了又添加了内部类只是名字相同,这样的话就是new一个对象,优先找内部类的是吧
回复 使用道具 举报
monian 发表于 2017-2-8 21:09
我的问题都没人解决不开心

不是一个ArrayList类哦, asList方法返回的这个ArrayList对象是个内部类对象
回复 使用道具 举报
受教受教!!!!!
回复 使用道具 举报
看完贴以后,真心学到了东西。。。赞一个
回复 使用道具 举报
我的问题都没人解决不开心
回复 使用道具 举报
受教受教~
回复 使用道具 举报
赞一个.....................................
回复 使用道具 举报
支持,顶起来
回复 使用道具 举报
晚上好,这么晚了还在学习
回复 使用道具 举报
来支持下
回复 使用道具 举报
分析的很好,很有条理,思路清晰,向贤哥学习
回复 使用道具 举报
为什么asList()方法中返回的ArrayList()和我们平时所用的ArrayList动态数组不同,不都是通过new关键字产生实例,这里怎么区分实现
回复 使用道具 举报
晚上好,  大家还在学习吗?
回复 使用道具 举报
回复 使用道具 举报
newu 黑马帝 2017-2-4 21:33:18
20#
无回帖,不论坛
回复 使用道具 举报
厉害了,我的贤哥.支持支持
回复 使用道具 举报
回复 使用道具 举报 1 0
楼主厉害
回复 使用道具 举报
回复 使用道具 举报
新手报个到
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马