一、数组基础
(一)数组的初始化
(1)如何声明定义一个一维数组
`int [] array1; double [] array2; boolean [] array3;
string [] array4;
object [] array5;`
(2)怎么初始化一个一维数组?
(a)静态初始化
int [] array = {1,2,3,4};
注意:大括号后面是有分号的
(b)动态初始化
int [] array = new int[5];//这里的5表示数组的元素个数,初始化一个5个长度的int类型数组,每一个元素默认值0
string [] array = new string[6]; //初始化6个长度的String 类型数组,每个元素默认值为null
(3) 什么时候采用静态初始化方式,什么时候采用动态初始化方式?
当你存储数组的时候,确定数组中存储的那些具体的元素的时,采用静态初始化方式,
当你创建的数组的,不确定将来数组中存储那些数据,你可以采用动态初始化的方式,预先分配内存空间
(二) 认识数组
(1)Java语言中的数组是一种引用数据类型,不属于基本数据类型,数组的父类是Object。
(2)数组实际上是一种容器,可以同时容纳多个元素。
(3)数组当中可以存储基本数据类型的数据,也可以存储引用数据类型的数据。
(4)数组是引用类型,所以数组对象是在堆内存当中的,(数组是存储在堆当中的)。
(6)对于数组当中存储的是“java对象”的话,实际上存储的是对象的"引用(内存地址)"(数组中不能直接存储Java对象)
(7)数组一旦创建,长度不可变。
二、数组内存结构
(一)一维内存结构
(1)数组在内存中的存储原理?
(a)所以数组对象都有length属性(java自带),用来获取数组中元素的个数。
(b)java中的数组要求数组中的元素的类型要统一,比如Int类型数组只能存储int类型。(存储的类型统一)
person类型数组只能存储person类型。
(c)数组在内存方面存储的时候,数组中的元素内存地址(存储的每一个元素都是有规则的并且挨着排列的)是连续的,内存地址连续,这是数组存储元素的特点(特色)。数组实际上是数据结构
(d)所以的数组,都是拿着第一个小方框的内存地址,作为整个数组对象的内存地址。
(e)数组中每一个元素都是有下标的,下标以0开始,以1递增,最后一个元素的下标是length-1
(f)下标是非常重要的,因为我们对数组中元素进行存取的时候,都是需要通过下标进行。
(2)数组这种数据结构的优点和缺点?
优点:查询/查找/检索某个下标上的元素时效率极高,可以说是查询效率最高的一个数据结构。
为什么检索效率高?
第一:每一个元素的内存地址在空间存储上是连续的。
第二:每一个元素类型相同,所以占用空间大小一样。
第三:知道第一个元素内存地址,知道每一个元素占用空间的大小,又知道下标。所以通过一个数学表达式就可以计算出某个下标上元素的内存地址。直接通过内存地址定位元素,所以数组的检索效率是最高的。
数组中存储100个元素,或者存储100万个元素,在元素查询/检索方面,效率是相同的,因为数组中元素查找的时候不会一个一个找,是通过数学表达式计算出来的。(算出一个内存地址,直接定位的)
缺点:
第一 由于为了保证数组中每一个元素的内存地址连续,所以在数组上随机删除或者增加元素的时候,效率极低,因为随机增删元素会涉及到后面元素统一向前或者向后位移的操作。
第二 数组中不能存储大数据量,为什么?
因为很难在内存空间上找到一块特别大的连续的内存空间。
注意:对于数组中最后一个元素的增删,是没有效率影响的。
(二)二维内存结构
我一直感觉二维数组的内存结构和一维数组的引用类型内存结构特别的像。
三、方法的参数是数组
(1)
packageArray; public class ArrayTest03{ public static void main(String[]args){ //静态的方式传递
int[]array={1,2,3,4};
show(array); //采用动态的方式传递
int[]array1=newint[6];
show(array1);
} public static void show(int[]array){ for(inti=0;i<array.length;i++){
System.out.println(array[i]);
}
}
}
(2)如果直接传递一个静态数组
(3)直接采用动态数组的传递方式
四、数组的扩容
在java开发中,数组长度一旦确定不可变,那么数组满了怎么办?
这个时候就需要扩容了。先新建一个大容量的数组,然后将小容量数组中的数据一个一个拷贝到大数组当中。
结论:数组扩容效率较低,因为涉及到拷贝的问题。所以在以后的开发中请注意:尽可能少的进行数组的拷贝。
可以在创建数组对象的时候预估计一下多长合适,最好预估准确,这样可以减少数组的扩容次数。提供效率。
内存图:
例子:
Object [] objs = {new Object(),new Object(),new Object()};
Object [] newobjs = new Object[10];
System.arraycopy(objs,0,newObjs,0,objs.length)
五、如何进行排序
Arrays工具类的使用
public class ArraysTest{
public static void main(String[] args){
//java.util.Arrays;工具类中有哪些方法,我们开发的时候需要参考API帮助文档
int [] arr = {3,6,5,12,1,2};
//排序
Array.sort(arr);
//输出
for(int i =0; i<arr.length;i++){
System.out.println(arr[i]);
}
//二分查找(建立在排序的基础之上)
int index = Arrays.binarySearch(arr,5);
System.out.println(index == -1? "该元素不存在":"该元素下标是:"+index)
}
}
总结,其实数组和之前的内容一模一样,其实并没有新东西,就比方说在内存图中的结构和面向对象引用类一模一样,存储数据和变量也没有什么不同。只不过把之前的东西总结了成了数组,这样运用起来可能更加方便一些。
参考文章: