2020-06-06
探究数组
1:概念
数组是一个线性结构,它用一组连续的内存空间地址储存相同类型的数据。
>连续的内存地址:计算机在分配内存空间的时候都会对应分配一个内存地址,连续的内存的空间就是连续的内存地址,计算机通过访问内存地址访问内存地址中储存的值。
>相同类型:数据所占内存地址大小一样(字节大小)。
2:特性
>随机访问
数组如何随机访问数据原理:
以一个长度为10的int类型数组为列 int[] i = new int[10];
此时计算机分配的内存地址为1000~1039;长度为10,int类型的数据占4个字节,所以内存地址大小为40。内存块的首地址base_address = 1000;
如图(图片来源于网上):
首先我们来看看这样的一个公式:
a [i]_address = base_address + i * data_type_size ;
>base_address:内存块的首地址
>i:下标(元素的偏移量)
>data_type_size:数据的字节大小
每一个元素占用4个字节内存空间(本列中是int)
a[0]_address = 1000 = 1000 + 0 * 4 ;
a[1]_address = 1004 = 1000 + 1 * 4 ;
a[2]_address = 1008 = 1000 + 2 * 4 ;
.....................
a[i]_address = 1000 + i * data_type_size ;
这就是数组下标随机访问的原理,通过下标计算出对应的内存空间地址,找到对应的值,时间复杂度o(1)。
3:数组下标为什么从0开始
首先假设我们从1开始,则:
a [i]_address = base_address + (i - 1 ) * data_type_size ;
此时就会多一步运算的操作。因此就会提升运算的效率。
假设从0开始,则:
a [i]_address = base_address + i * data_type_size ;
此时就少了一个减法步骤,提供了计算效率。
·数组为什么必须使用相同类型
我们都知道每种数据类型,占用内存空间有所不同。比如:
Byte:1字节
Char:2字节
Int:4字节
Double:8字节
假设数组支持储存不同类型数据,就无法根据下标(偏移量)来实现随机访问
a [i]_address = base_address + i * data_type_size ;
4:数组为什么不能扩容
假设数组支持扩容:
new int[10], jvm会分配40个字节内存空间,此时jvm给另外的对象分配了内存空间1040 ~ xxxx; 现在数组进行扩容时,发现数组后面的内存空间被人使用了,无法扩容。无法扩容的原因是数组的内存空间分配必须是连续的内存。
如果一旦不连续的扩容,就会导致随机访问特性失效。有人说可以预留,但是你想想你根本不知道你数组扩容多大,这个时候你预留多少的连续内存空间了????
因此这也是为什么要求数组的内存空间分配必须是连续的,在创建数组的时候就指定大小。
欢迎大家关注我的公众号。一起探讨技术。《大表哥编程》