
Java数组集合迭代器?
但是集合中却只能存放引用(内存地址),即使是基本数据类型也会自动转为包装类型,那么为什么说数组就是集合?
(2)关于Foreach,看了一些资料,说增强for底层实际调用了Iterator迭代器进行迭代,但是增强for也同样适用一维数组的遍历,那么难道一维数组也能获取迭代器对象? 展开
这是一个很好的问题,如果不是看到了这个问题,我平时还真没注意过这一点!
首先确认,数组并不是集合,集合的定义是:存储多个同一类型的数据的容器称之为 集合 ,集合的大小不固定,而数组的大小是固定的。同时,由于泛型的限制,集合中只能存储对象,而无法像数组那样直接存储基本数据类型(必须要封箱为包装类)。
要解决题主的疑问,我们写一个示例来观察一下。
在一个类中,我们编写三个增强for循环,其中第一个循环遍历基本数据类型数组,第二个循环遍历引用类型数组,第三个循环遍历List集合。
编译运行这个程序,可以看到程序正常输出了我们想要的结果:
下面,让我们去看一下反编译后的字节码文件:
首先是遍历数组的两个循环:
可以看到,虽然使用了增强for循环,事实上,编译之后就变成了普通for循环。即使数组中存储的是引用类型,依然和普通数据类型一样,用的是普通for循环,而不是通过迭代器进行遍历。
再看集合的增强for循环:
集合就和我们想象的一样了,通过迭代器遍历整个集合。
总结:
对于集合而言,增强for循环的确是通过迭代器进行遍历的,但当增强for循环针对的是数组时,增强for循环就会被编译为普通的for循环。即,遍历数组的依然是普通for循环的原理,增强for循环只不过是简化了这个过程。
其实主要是他说数组就是集合误导了我,list集合底层是可自动扩容数组,其实应该不是一个东西,可以理解为list集合不允许直接放基本数据类型的元素到底层的数组中吗?
至于增强for循环应该算是动态的,等于具体要看循环什么东西,才能决定他底层采用什么方式去循环?
ArrayList的底层实现的确是数组,但我们不能说数组就是一个集合,只能说我们使用数组可以实现一个集合。
使用泛型可以强制规定一个实例化出的ArrayList必须存储某种类型的数据。如果在实例化时不指定泛型,那么我们就可以存储多种类型的数据,但这就导致了一个问题:ArrayList底层是使用数组存储的,而一个数组只能存储一种数据类型,如果你想存储多种数据类型,那么你要怎么声明这个数组呢?如果允许存入基本数据类型的话,那么这个数组就只能存储这种类型的数据了。因此,我们需要一种高级的类型,它允许任意类型都可以转换为这种类型——那就是Object类型了。我们就可以将这个数组声明为一个Object数组,当我们向这个数组中写入多种类型的数据时,即使是基本数据类型,也会被封箱为包装类,这样我们就可以存储多种数据类型了。
而且,声明数组必须需要一种类型,如果你想存储一个基本数据类型的数据,那你必须要把底层的数组声明为这个数据的类型。但我们是无法直接判断一个基本数据类型的类型的,只能通过获取其包装类的类型来判断其对应的基本类型……但如果你都走到这一步了,干嘛不用包装类还非要用基本数据类型呢?所以还不如就用包装类好了。
关于增强for循环,这是一种语言特性,具体的实现原理应该是虚拟机级别的,但看上面示例,应该就是动态判断的了。