数组是一种非常常用的数据结构,它是有序数据的集合,数组中每个元素具有相同的数组名,根据数组名和下标来唯一地确定数组中的元素。
数组分为一维数组和多维数组。
从存储的角度看,数组是一组相关的存储单元,这些存储单元具有相同的名字和数据类型,并且这些存储单元是连续存储单元(紧邻在一起)。
要引用数组的某个特定的数据项(数组元素),需要说明数组名和该特定数据项在数组中的序号(下标)。
image.png

一维数组与多维数组

• 一维数组 当数组中每个元素都只带有一个下标时,称这样的数组为一维数组。int arr[];
• 多维数组 当数组中每个元素都带有n(n>1)个下标时,称这样的数组为多维数组。int matrix[][];

数组类型

• 数组元素的类型 数组的所有元素都有相同的类型,称为数组的元素类型。
• 数组类型
− 如果数组的元素类型是T,则将数组本身的类型写作T后接若干对空方括号[]
− 如果数组本身是一维数组,则写作T[]
− 如果数组本身是二维数组,则写作T[][]
• 数组元素的类型可以是哪些类型
− 数组类型可以是任何类型,包括基本类型或引用类型,特别地:
− 允许数组把接口类型作为其元素类型。这样,一个数组的元素可以把空引用或者实现该接口的任何类型的实例作为他们的值。
− 允许数组把abstract类类型作为其元素类型。这样,一个数组的元素可以把空引用或者自身不是abstract的abstract类的任何子类的实例作为它们的值。

声明一维数组变量

• 数组变量
− 数组类型的变量存储一个指向数组(对象)的引用。
− 声明数组类型的变量不会创建一个数组对象,或者为数组元素分配任何存储空间。它只会创建变量本身,该变量可以存储一个指向数组对象的引用。
• 声明数组变量
− 在程序中使用数组时,必须声明一个引用数组的变量,并指明其数组元素的类型。
• 声明一维数组变量的语法:
image.png

  1. new elementType[arraySize]
  2. elementType[] arrayRefVar; arrayRefVar = new elementType[arraySize];

数组访问

数组元素由数组名及其下标(序号)标识。
数组的元素可以被数组访问表达式访问。
arrayRefVAr[index] 数组变量名[下标]
• 关于数组下标的类型
− 数组的下标必须是int值;short、byte或char值也可以用作下标,这是由于可以对它们进行一元数值提升,使之成为int值。
− 如果试图利用long下标值访问数组元素,则会导致编译时错误。
− 在运行时会检查所有的数组访问:如果试图使用小于0或者大于或等于数组长度的下标,则会抛出一个 ArrayIndexOutOfBoundsExceptio

  1. package com.buptnu;
  2. public class Array1
  3. {
  4. public static void main(String[] args)
  5. {
  6. double[] myArray;
  7. myArray = new double[5];
  8. myArray[0] = 2.3;
  9. myArray[1] = 5.6;
  10. myArray[2] = 7.12;
  11. myArray[3] = 3.25;
  12. myArray[4] = 2.3;
  13. for (int i = 0; i <= myArray.length - 1; i++)
  14. {
  15. System.out.println(myArray[i]);
  16. }
  17. }
  18. }

数组变量与数组对象的内存结构示意图

double[] myArray; myArray = new double[5];
image.png
初始值是默认值0.0,之后再用其它语句给数组元素赋值,如myArray[0] = 2.3;
引用与普通指针的区别在于,指针包含的是对象的内存地址,而引用则是由系统所管理的引用标识,该标识可以被系统重新定位到一个内存地址上。这种间接访问对象的模式增强了系统对被引用对象的控制。

一维数组的声明与内存分配

在Java语言中,数组是作为非原始数据类型来处理的。
对于非原始数据类型,在声明变量时并不会分配内存,必须另外进行内存分配的操作。所以在使用数组的时候,除了要声明数组之外,还必须进行给数组分配内存的工作。
一维数组内存分配的格式为:数组名= new 数据类型[个数];
image.png
在这个图中,长方体代表内存中分配给数组变量score的一块存储空间,存储空间中使用问号“?”,表示此时在该存储单元中的存储内容是未知的。
这是因为此时,score尚未执行任何数组实体的地址。
这段程序的第二行,是给数组score分配内存。这行语句,告诉编译器要给数组score配置可供保存4个整型数据的存储空间,并把这块存储空间的参考地址(reference)赋给变量score。
image.png
这个图说明了分配内存并把内存的首地址赋给数组类型变量score的过程。
所谓首地址,就是一块内存的起始地址。
首先命令“new int[4]”,命令编译器分配一块可以存放4个整数的存储空间,用来存放整型数组score的4个元素,这四个元素的名字是score[0]、score[1]、score[2]和score[3]。
我们假设这块内存的起始地址是0x1000。由于在Java中,整型数据类型占用的存储单元是4个字节,所以score[0]的地址是0x1000,score[1]的地址是0x1004,score[2]的地址是0x1008,score[3]的地址是0x1012。
其次,在分配了这块内存之后,就要把这块内存的起始地址,也就是这块内存的参考(reference)赋给数组变量score。
这个工作是通过语句中的赋值运算符,也就是“=”来完成的。
赋值运算符把这块内存的首地址,也就是0x1000赋给数组变量score,知道这里,变量score的存储空间中的存储内容才是一个确定的值,这就是0x1000。
总之,数组变量score中保存的内容,并非是数组实体,而是数组实体的参考地址。
另外,我们还可以把数组的声明和给数组分配内存的工作写在一条语句当中。
它的格式如下:int score[] = new int[4];

一维数组赋初值

除了先用new运算符给数组分配存储空间,然后直接引用数组元素给数组赋值之外,还可以直接给数组赋值,并定义数组的大小。后一种办法就称为给数组赋初值。例如:

  1. int a[]={1,2,3,4,5}; char c[]={'a','b','c','北','京'};

数组的大小和数组元素的默认值

• 数组的大小
− 当给数组分配空间时,必须通过指定该数组能够存储的元素个数来确定数组大小。
− 创建数组之后就不能再修改它的大小。
− 可以使用arrayRefVar。length求得数组的大小。
• 数组元素的默认值
− 当创建数组后,他的元素被赋予默认值。
− 这种类型数据的默认值
数值型数据的默认值是0
char型数据的默认值是’\u0000’
boolean数据的默认值是false
引用类型数据的默认值是null