本帖最后由 大山哥哥 于 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里面并没有增删元素的方法即add和remove方法,ArrayList类里面没有但是却能使用add和remove方法,那只能说明这两个方法是父类AbstractList的,所以我们去查看AbstractList的源码
原来AbstractList里面的add和remove方法里面仅有一句抛出异常的代码,所以当我们用数组转成的集合对象调用add和remove方法的时候会报出此异常。但是那为什么其他集合比如LinkedList或者Vector集合调用add和remove却不报此异常呢?那是因为LinkedList和Vector重写了add和remove方法,他们的对象使用的是自己的这两个方法,而不是使用的AbstractList的add和remove方法。
|