1. Java数组的定义:
1) 和其它编程语言的数组定义基本相同,具有2要素,分别是类型一致(数组中的数据都是一种类型的)和定长(初始化时就已经确定长度,这也意味着数组的内存空间也确定了,即大小不变了);
2) 在Java中数组类型也是一种引用类型,底层是用面向对象的类实现的;
3) 定义数组:支持两种格式
i. Java格式:type[] arrayName;
ii. 传统的C语言格式:type arrayName[]; // 为了满足C程序员的编程习惯
!!更加推荐Java风格的,因为其类型一目了然(type[]类型),一看就知道是个数组;
!!上面的arrayName就是个引用类型变量,其类型是type[];
4) 定义数组变量时不能指定数组长度,例如type[5] arrayName是不对的,因为type[]是一种类型,不能出现和初始化相关的内容,而指定数组的长度是初始化时指定的!
2. 数组初始化:
1) 毕竟type[]也是一种面向对象的类型,因此也需要使用new运算符来创建数组对象(开辟内存空间);
2) 支持两种初始化方式:
i. 静态初始化:不指定长度,但显示指定每个数组元素的值(Java自动根据初始化元素的个数决定数组长度);
ii. 动态初始化:只指定一个长度,但不给出每个元素的值,让Java自动赋予每个元素初始化值(0/null);
!!不能同时结合两种初始化方式初始化,否则编译器会直接报错!Java将这两种初始化逻辑严格地分开了;
3) 静态初始化:
i. 格式:arrayName = new type[] {ele1, ele2, ele3...};
ii. 还有一种简化版的静态初始化,其格式是:type[] arraryName = {ele1, ele2, ele3...}; // 可以不用写new type[],其风格和C语言一样
!!但不过简化版的语法只能在定义数组变量的同时使用,不能定义和初始化分开!!否则会编译报错!而完整版的可以分开;
iii. 当然支持继承的特性,例如:Object[] objArrary = new String[] {"xxx", "xxx"...}; // 向上转化类型
5) 动态初始化:
i. 格式:arrayName = new type[len];
ii. 这种方式往往应用在长度较大的数组上;
iii. Java会自动为每个元素赋予初值(0/null);
!!不能同时使用两种初始化方法(例如:int[] arr = new int[5] {1, 2, 3, 4, 5};),会直接编译报错的!!
3. 使用数组:
1) 使用方法和C语言基本一样,使用[]索引数组中的元素;
2) length属性:arrayName.length将返回数组长度,这个非常常用,可以利用这个在for循环中迭代
3) forEach迭代:
i. Java5引入的新的数组、集合迭代方法,和Python的迭代相同;
ii. 格式:for (type varName: array | collection) { ... }
iii. 即用一个临时变量varName来逐个接受数组|集合中的每个元素,varName就是那个迭代值,它是一个临时变量,不能用于改变数组元素的值,相当于数组的视图;
iv. type必须要和数组/集合中元素的类型相匹配;
v. 示例:
[java] view plain copy
- int[] arr = new int[] {1, 2, 3, 4, 5};
- for (int v: arr) {
- System.out.println(v);
- }
!无需用迭代计数变量i来迭代了!很方便!
!!注意:上述不能用v来改变数组中的元素,因为v只是一个临时变量(如果在for循环体中写这样的语句,v = xxx;之类的并不能实际改变数组中的元素!);
4. 多维数组:
1) Java其实没有多维数组,多维数组其实就是通过一维数组模拟的;
2) 比如二维数组,其实就是一个一维数组,数组中的每个元素都是一个一维子数组,这就形成了一个二维数组;
3) 虽然多维数组的意义是这样的,但是实际编程时不能根据意义编写,因为Java专门提供了多维数组的语法:
i. 你可能会想type[]是一个一维数组类型,那么type[] + []不就是type[]类型的一维数组了吗?那不是后面那个[]代表行,前面那个[]代表列了吗?
ii.
这在理解上没问题,确实是这样,但是Java的多维数组语法并不这样定义,在上面的例子中,前面的[]代表行,后面的那个[]代表列,因为在编程语法上这样更符合一般多为数组的使用习惯,因此就不用前面的那种非常别扭的定义(虽然前一种定义非常合理,但是使用起来特别别扭);
iii. 因此Java的多维数组type[][][]...,越前面的[]代表越高的层级,越后面的[]代表越低的层级(即越前面的[]代表越高维,越后面的[]代表越低维);
4) 多维数组的初始化:和一维数组一样,也是静态和动态两种
i. 原则还是一样的,两者不能同时使用;
ii. new type[][].. 的[]中不能有任何东西就是静态,如果任意一个[]有数字那就是动态;
iii. 静态就必须在new type[][]...后面使用{}给出指定初始值,动态就不能用{}指定初始值,不管数组出现在哪个[]中;
iv. 例如:
[java] view plain copy
- int[][] a = new int[][] {new int[3], new int[] {1, 2, 3}, {3, 4, 5}};
- int[][] b = {new int[3], new int[] {1, 2, 3}, {3, 4, 5}};
- int[][] c = new int[2][];
- int[][] d = new int[][3]; // 错误!!多维数组必须动态初始化时必须先指定高维!
- int[][] e = new int[2][3];
- int[][] f = new int[2][] {new int[3], new int[4]}; // 错误!!动静混用!
!!可以看到,在任何一维都可以使用静态简化版初始化,非常灵活非常骚;