1.一维数组声明

下面三种方式均可取:

x = new int[3];

y = new int[]{1, 2, 3, 4, 5};

int[] z = {9, 10, 11, 12, 13};

方式1:创建一个大小为3的int型数组,x为对该数组的引用,默认初始值均为0
方式2:创建一个int数组,里面的值为{1,2,3,4,5},Java会自动计算出该数组的长度,y为对该数组的引用

对于方式1与方式2,需要提前声明x与y是对数组的引用:
int[] x, y;
引用的内存大小均为64bit请注意,如果我们对y重新赋值:
y = new int[]{-1, 2, 5, 4, 99};
那么我们将永久丢失数组{1, 2, 3, 4, 5}的地址,无法再找到并使用该数组,因为已经被垃圾回收。
方式3:使用这种方法创建数组不需要使用关键字new,但是声明数组的同时也声明了变量z

字符型数组

String[] s = new String[6];
对于这样的声明方式,Java会自动赋予初值,int默认全是0,而String默认是null,是字符串的引用
使用以下语句:
s[4] = "ketchup";
则会将"ketchup"的地址传到s[4]

System.arraycopy()

拷贝数组的方法,System.arraycopy(array1,start1,array2,start2,length),该方法有五个参数,其含义为:

array1:被拷贝的数组名A
start1:从数组A的下标为start1的项开始
array2:拷贝至的数组名B
start2:从数组B的下标为statrt2的项开始
length:从数组A的下标为start1的项开始,拷贝length项
举例,System.arraycopy(b, 0,x, 3, 2)意思是将数组x的下标为3项开始,数组x后面的2项全部被替换为,从数组b的第0项开始往后2位,等同于python的x[3:5] = b[0:2]
当然朴素的方法是通过一个循环,将x[i]=y[i],也可以实现数组拷贝,但是System.arraycopy()在处理大数组时比循环更快,原因是它更接近底层硬件,且该方法是非破坏性方法,这意味着它不会对原来被拷贝数组作出改动


2.二维数组

二维数组实际上是数组的数组,听起来可能比较拗口,比如:

int[][] pascalsTriangle;
pascalsTriangle = new int[4][];

声明了一个长度为4的pascalsTriangle的数组,该数组的每一项均为数组的引用,每一项均可指向一个一维数组,因此初始值全为null

对数组的每一项赋值:

pascalsTriangle[0] = new int[]{1};
pascalsTriangle[1] = new int[]{1, 1};
pascalsTriangle[2] = new int[]{1, 2, 1};
pascalsTriangle[3] = new int[]{1, 3, 3, 1};

将会使数组的第0,1,2,3项分别指向四个不同的int型数组

由于pascalsTriangle数组的每一项均为int类型数组的引用,创建一个新的数组并将pascalsTriangle数组的某一项值赋予给新数组的某一项,那么对新数组的该项进行改动时也能印象原来指向的int数组

int[] rowTwo = pascalsTriangle[2];
rowTwo[1] = -5;

这里定义了一个rowTwo的变量作为数组引用,rowTwo存放pascalsTriangle第2项的值,而pascalsTriangle第2项是对数组{1, 2, 1}的引用,因此rowTwo也成为对数组{1, 2, 1}的引用,rowTwo指向数组{1, 2, 1},那么对rowTwo[1]进行修改,原来的{1, 2, 1}也就会变成{1, -5, 1}
注意以下声明方式对于数组的初始化不同

int[][] matrix;
① matrix = new int[4][];
② matrix = new int[4][4];

对于①,创建一个长度为4的matrix数组,每一项的将作为一维int数组的引用,因此初始值全为null,仅创建了一个数组
对于②,在创建引用数组的同时也将4个int型数组创建了,且每一个int型数组的长度为4,默认初始化为0,因此声明②同时创建了五个数组

小练习

为了确定您是否掌握二维数组,一个小测验

int[][] x = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

int[][] z = new int[3][];
z[0] = x[0];
z[1] = x[1];
z[2] = x[2];
z[0][0] = -z[0][0];

int[][] w = new int[3][3];
System.arraycopy(x[0], 0, w[0], 0, 3);
System.arraycopy(x[1], 0, w[1], 0, 3);
System.arraycopy(x[2], 0, w[2], 0, 3);
w[0][0] = -w[0][0];

After running the code below, what will be the values of x[0] [0] and w[0] [0]?

answer:
x[0][0]: -1, w[0][0]: 1


3.数组和类比较

数组和类都可以用来表示一堆内存盒。在这两种情况下,内存盒的数量都是固定的,即数组的长度不能改变,就像类字段不能添加或删除一样

数组和类中内存盒的主要区别:

  • 数组使用 [] 符号进行编号和访问,类使用 . 符号命名和访问。
  • 数组中的元素必须都是相同的类型。类的元素可以是不同的类型。

因此,当我们使用Array[index]去访问数组元素时的确可行,但是如果p是一个类的实例,使用p[index]则编译器会报错,不推荐使用该方法访问类的成员(风格糟糕),如果你的确想这么做的话,可以使用Java的reflection API

与其他语言中的数组相比,Java的数组:

没有类似于“切片”的特殊语法(例如在 Python 中)
不能收缩或扩展(例如在 Ruby 中)
没有成员方法(例如在 Javascript 中,但是有Array.length可直接得出数组长度)
必须包含相同类型的值(与 Python 不同)


Fallenpetals
4 声望9 粉丝