Java漫游笔记-02-06-数组

本质

首先,数组本质上是一个类,从 2 个方面可以很明显地判断出来:
第一,它的初始化使用了 new
第二,它有 length 属性,它还实现了 Object 这个超类所有的方法。

声明

建议使用这样的方式:int[] array ,而不是: int array []
原因很简单:int[] 是类型, array 是变量名,不应混在一起。

初始化

java 允许在运行期确定数组大小,因此不仅可以使用常量声明数组的长度,还可以使用变量来声明数组的长度,例如:

1
int[] array = new int[100];

或者是:

1
2
int len = 100;
int[] array = new int[len];

对于元素较少的数组,也可以这样初始化:

1
int[] otherArray = { 1, 2, 3 };

相当于:

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

还可以定义,长度为 0 的数组:

1
int[] array = {};

或者是:

1
int[] array = new int[0];

当你需要返回一个空的数组(不是 null ),你就可以这么用。

多维数组

一维数组,可以看作是表格的一行(相当于一条线,只有 x 轴);
二维数组,可以看作是一个表格(相当于一个面,有 x ,y 轴);
三维数组,可以看作是一个三维的坐标系(相当于一个立体,有 x ,y ,z 轴)。
更多维度的,恕我太笨了,还想象不出来,所以目前为止,还不敢用。

1
2
3
String[][] table = {
{ "A1", "A2", "A3" },
{ "B1", "B2" } };

实际上,任何多维度的数组,都可以解释为“数组的数组”
如果从这个角度来看,也就没有了所谓的多维数组。
这样说来,为什么 java 的多维数组,可以是不规则的,也就很好理解了。
这也可以解释,为什么定义二维数组时,第一个方括号,需要显示地声明长度,而第二个就不需要了:

1
2
String[][] table = new String[100][];
table[0] = new String[10];

复制数组

关于数组的复制,可以使用:System.arraycopy() 或者是 Arrays.copyOf()
Arrays.copyOf() 实际上也是调用了 System.arraycopy()

数组复制的一个比较典型的使用场景是,往一个 ArrayList 的指定位置插入 1 个元素。

另外,需要注意的是,不要幻想直接通过 = 来复制数组
因为,前面已经说过数组本质上是一个类,你通过 = 复制的,只是一个引用而已。

其他

除了上面的数组复制,java.util.Arrays 还提供很多操作数组的方法。
例如:排序( sort() )、搜索( binarySearch() )、比较( equals() )、填充( fill() )以及转换( asList() )等。

JDK 1.8 ,还新增了并行排序算法:Arrays. parallelSort()
从我粗略的测试结果(小霸王,2个CPU 4G RAM)来看:
当数据量比较大的时候(例如 10,000,000 个数字),可以考虑使用 parallelSort()
当数据量比较小的时候,parallelSort() 并没有优势,甚至更慢。

其实,无论是 Arrays.sort() 还是 Arrays. parallelSort() 都会根据数据量来选择使用排序算法:
Arrays 的源码中也可以看到:

1
private static final int MIN_ARRAY_SORT_GRAN = 1 << 13;

当数组长度小于 213 = 8192 时,实际上都会快速排序。