黑马程序员技术交流社区

标题: 【济南中心】潜意识中asList方法的两个迷惑 [打印本页]

作者: 大山哥哥    时间: 2017-1-20 15:01
标题: 【济南中心】潜意识中asList方法的两个迷惑
本帖最后由 大山哥哥 于 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方法。

作者: 职业规划-王雪老师    时间: 2017-1-20 15:16
逢贴必读,66666666666666666666,厉害了我的哥
作者: 大山哥哥    时间: 2017-1-20 16:24
职业规划-王雪老师 发表于 2017-1-20 15:16
逢贴必读,66666666666666666666,厉害了我的哥

O(∩_∩)O哈哈~
作者: 大东哥哥丶    时间: 2017-1-20 17:40
xian哥帖子,必属精品
作者: duanqichao    时间: 2017-1-20 22:11
向贤哥学习,以后争取多写点自己理解的东西和大家共享。

作者: 袁志娜    时间: 2017-1-20 23:06

作者: a469517790    时间: 2017-1-21 20:43
xian哥帖子,必属精品
作者: 小虎同学    时间: 2017-1-21 21:53
可可以了,不错,学习膜拜中

作者: zhoubinjian    时间: 2017-1-21 23:55
来支持下
作者: 苏小溪    时间: 2017-1-23 16:31
厉害了,我的贤哥

作者: flying81621    时间: 2017-1-26 21:47
厉害,见识了
作者: flying81621    时间: 2017-1-28 16:35
为什么看不到全部的内容?只能看到一部分
作者: guyouzhong    时间: 2017-1-29 08:47
word天,叼

作者: 宇轩H    时间: 2017-1-29 14:31
................
作者: 赵大侠    时间: 2017-1-29 18:47
新手报个到
作者: 夜雨清澜    时间: 2017-2-3 14:36
厉害了我的哥

作者: AP_P    时间: 2017-2-4 10:35
楼主厉害
作者: 13699475949    时间: 2017-2-4 14:44
好好学习,天天向上

作者: 经过    时间: 2017-2-4 19:51
厉害了,我的贤哥.支持支持
作者: newu    时间: 2017-2-4 21:33
无回帖,不论坛

作者: sb123456    时间: 2017-2-4 22:20
厉害

作者: sb123456    时间: 2017-2-4 23:15
晚上好,  大家还在学习吗?
作者: monian    时间: 2017-2-7 16:16
为什么asList()方法中返回的ArrayList()和我们平时所用的ArrayList动态数组不同,不都是通过new关键字产生实例,这里怎么区分实现
作者: 笑对明天    时间: 2017-2-7 16:40
分析的很好,很有条理,思路清晰,向贤哥学习
作者: zhoubinjian    时间: 2017-2-7 22:20
来支持下
作者: 唐勇2017    时间: 2017-2-7 23:43
晚上好,这么晚了还在学习
作者: 灬Wonder    时间: 2017-2-8 12:58
支持,顶起来
作者: 灬Wonder    时间: 2017-2-8 12:59
赞一个.....................................
作者: blackmustang    时间: 2017-2-8 18:17
受教受教~
作者: monian    时间: 2017-2-8 21:09
我的问题都没人解决不开心
作者: 列兵程序员    时间: 2017-2-8 21:37
看完贴以后,真心学到了东西。。。赞一个
作者: flying81621    时间: 2017-2-9 16:40
受教受教!!!!!
作者: 大山哥哥    时间: 2017-2-9 16:59
monian 发表于 2017-2-8 21:09
我的问题都没人解决不开心

不是一个ArrayList类哦, asList方法返回的这个ArrayList对象是个内部类对象
作者: kimoti    时间: 2017-2-10 11:44
干了Java那么多年还真没注意过这个问题,又学到了
作者: monian    时间: 2017-2-12 22:44
大山哥哥 发表于 2017-2-9 16:59
不是一个ArrayList类哦, asList方法返回的这个ArrayList对象是个内部类对象

谢谢,看了源码终于知道了又添加了内部类只是名字相同,这样的话就是new一个对象,优先找内部类的是吧




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