本质
首先,数组本质上是一个类,从 2 个方面可以很明显地判断出来:
第一,它的初始化使用了 new
;
第二,它有 length
属性,它还实现了 Object
这个超类所有的方法。
声明
建议使用这样的方式:int[] array
,而不是: 。int array []
原因很简单:int[]
是类型, array
是变量名,不应混在一起。
初始化
java 允许在运行期确定数组大小,因此不仅可以使用常量声明数组的长度,还可以使用变量来声明数组的长度,例如:
1 | int[] array = new int[100]; |
或者是:
1 | int len = 100; |
对于元素较少的数组,也可以这样初始化:
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 | String[][] table = { |
实际上,任何多维度的数组,都可以解释为“数组的数组”。
如果从这个角度来看,也就没有了所谓的多维数组。
这样说来,为什么 java 的多维数组,可以是不规则的,也就很好理解了。
这也可以解释,为什么定义二维数组时,第一个方括号,需要显示地声明长度,而第二个就不需要了:
1 | String[][] table = new String[100][]; |
复制数组
关于数组的复制,可以使用: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 时,实际上都会快速排序。