在大部分编程语言中都有数组这种数据存储结构,而且通俗易懂 ,对于数据结构初学着来说数组作为起步点最适合不过了。
那么什么是数组呢?网上定义挺多的,这里我借用了《java编程思想第四版》的一段话:相同类型的,用同一个标识符名称封装到一起的一个对象序列或基本类型数据序列,使用方括号下标操作符 []来定义和使用。
我们为什么要用数组呢?假如我们要记录一个班60个同学的名字,一个变量一个变量定义就要定义60次了,使用数组的话我们只需要定义一个变量,工作量大大减少。
下面我把自己梳理出来的要点总结一下:
1、数组也是一种数据类型
在java数组中要求所有的数组元素具有相同的数据类型,因此在数组中数据元素的类型是唯一的。数组属于引用类型,例如int是一种基本数据类型,但int[]是一种引用数据类型
2、数组的定义
java有两种数组语法格式,如下:
int[] intArray;
int intArray[];
推荐第一种,因为可读性比较高,第一种我们可以理解为变量类型是int[],变量名是intArray;第二张理解为int类型的的变量 intArray[] (在c#语言中已经不再支持第二种语法)。因为数组是一种引用类型变量,因此使用数组定义一个变量时,仅仅表示定义了一个引用变量,未指向任何有效的内存。因此定义数组时不能指定数组的长度。
3、数组的初始化
初始化就是为数组的元素分配内存空间,并为每个数组元素赋初始值,初始化数组才可以使用。一旦分配了内存空间,数组的每个元素都会赋初始值,即使这个内存空间存储的内容是空的,这个空也是一个值,只不过为null,这点要记清楚。数组的初始化有两种方式,静态初始化和动态初始化。静态初始化由我们显式指定每个数组元素的初始值,由系统决定数组长度。动态初始化由我们指定数组长度,系统为数组的每个元素分配初始值。
int[] intArray=new int[]{1,2,3,4} //静态初始化,length为4
int[] intArray={1,2,3,4} //简易静态初始化,length为4
int[] intArray=new int[4]//动态初始化。length为4,四个元素的初始值均为0
值得注意的是动态初始化的初始值赋值规则和数组的数据元素类型有关系:
整数类型(byte,short,int和long)初始值为0
浮点类型(float和double)初始值为0.0
字符类型(char)初始值是'\u0000'
布尔类型(boolean)初始值是false
引用类型(类、接口和数组),则数组元素的值是null
4、数组元素的访问及赋值
访问数组元素通过数组引用变量后跟一个方括号,方括号里是数组元素的索引,这样便可以将数组元素当成一个普通变量使用。数组的索引从0开始到length-1结束,如果访问数组元素的索引值小于0或者大于length-1,编译不会报错,但运行会出现异常:java.lang.ArrayIndexOutOfBoundsException:N(数组索引越界)N就是试图访问的数组索引。如果要访问这个数组所有的数据元素可以使用以下两种常用的方法
int[] intArray={1,2,3,4};
for(int i=0;i<intArray.length;i++)
{
System.out.println(intArray[i]);
}
//或者
for(int i:intArray)
{
System.out.println(i);
}
5、数组内存分析
数组是一种引用数据类型,数组引用变量只是一个引用,数组元素和数据变量在内存里是分开存放的。数组对象存放在堆(heap)上,如果数组引用变量是一个局部变量,那么将被存储在栈(stack)内存中示意图如下:
访问堆内存中的数组元素程序只能通过intArray[i]的形式实现。如果堆内存中数据不再有任何引用指向自己,则这个数组将成为垃圾被回收。
6、数组的复制
使用System类的arraycopy()方法,参考下图
public static native void arraycopy(Object src,int srcPos,Object dest, int destPos,int length);
/**
src 表示源数组
srcPos 表示源数组起始下标
dest 表示目标数组
destPos 表示目标数组起始下标
int 表示复制数组的数据元素个数
*/
//测试
import java.util.Arrays;
public class Array {
public static void main(String[] args){
int[] intArrayA={1,2,3,4};
int[] intArrayB={11,22,33,44,55,66};
int[] intArrayC={111,222};
System.out.println(intArrayB);
System.arraycopy(intArrayA,0,intArrayB,0,4);
try {
System.arraycopy(intArrayA, 0, intArrayC, 0, 4);//目标数组容量不足以容纳源数组元素,
}catch(ArrayIndexOutOfBoundsException e){
System.out.println(e);
}
System.out.println(intArrayB);
System.out.println(Arrays.toString(intArrayB));
for(int i :intArrayB){
System.out.println(i);
}
}
}
/*
结果输出
[I@579bb367
java.lang.ArrayIndexOutOfBoundsException
[I@579bb367
[1, 2, 3, 4, 55, 66]
1
2
3
4
55
66
*/