第十六章 数组
标签: Java编程思想
对数组的基本看法是:使用整形索引访问其中的元素,并且容量不能改变。
16.1 数组
数组与其他容器之间的区别:效率,类型和保存基本类型的能力。
16.2 数组是第一级对象
无论使用哪一种类型的数组,数组标识符其实只是一个引用,指向在堆中创建的一个真实对象。这个对象用以保存指向其他对象的引用。
对象数组和基本类型数组在作用上几乎是相同的,唯一不同的是对象数组保存的是引用,基本数据类型保存的是值。
16.3 返回一个数组
package com.array1;
import java.util.Arrays;
import java.util.Random;
public class IceCream {
private static Random random = new Random(47);
private static final String[] FLAVORS = {
"Chocolate", "Strawberry", "Vanilla", "Rum Raisin"
};
public static String[] flavorsSet(int n) {
if (n > FLAVORS.length) {
throw new IllegalStateException("set toot big.");
}
String[] results = new String[n];
boolean[] picked = new boolean[FLAVORS.length];
for (int i = 0; i < n; i++) {
int t;
do {
t = random.nextInt(FLAVORS.length);
} while (picked[t]);
results[i] = FLAVORS[t];
picked[t] = true;
}
return results;
}
public static void main(String[] args) {
for (int i = 0; i < 7; i++) {
System.out.println(Arrays.toString(flavorsSet(3)));
}
}
}
output:
/usr/lib/jvm/java-8-oracle/bin/java -javaagent:/snap/intellij-idea-
[Vanilla, Strawberry, Chocolate]
[Chocolate, Vanilla, Strawberry]
[Vanilla, Strawberry, Rum Raisin]
[Strawberry, Chocolate, Vanilla]
[Rum Raisin, Chocolate, Vanilla]
[Vanilla, Chocolate, Strawberry]
[Strawberry, Chocolate, Rum Raisin]
Process finished with exit code 0
16.4 多维数组
多维数组的创建与一维数组相类似:
package com.array1;
import java.util.Arrays;
public class MultidemensionArray {
public static void main(String[] args) {
int[][] arr = new int[][]{
{1, 2},
{3, 4}
};
System.out.println(Arrays.deepToString(arr));
}
}
Arrays.deepToString()方法对于基本类型数组和对象数组都起作用。
16.5 数组与泛型
通常,数组不能与泛型很好的结合,不能实例化具有参数类型的数组。类型擦除会移除参数类型信息,而数组必须知道他们所持有的具体类型,以强制保证类型安全。
如果知道将来不会向上转型,并且需求也较为简单,那么仍旧可以创建泛型数组,事实上,泛型容器总是比泛型数组更好的选择。
16.6 创建测试数据
通常在测试数组和程序时,能够方便的生成填充了测试数据的数组将会很有帮助。
16.6.1 Arrrays.fill()
Arrays.fill()是java标准库中的一个方法,用同一个值填充各个位置,而针对对象而言,就是用同一个引用填充。
16.6.2 数据生成器
16.7 Arrays实用功能
在java.util.Arrays类中用于数组的static方法:
- equals() 比较两个数组是否相等,其中deepEquals()方法用于比较多维数组
- fill() 用同一个值或者引用填充数组
- sort() 用于对数组排序
- binarySearch() 用于对已经排序的数组进行查找
- toString() 产生数组的string表示
- hashCode() 产生数组的散列码
- asList() 将数组转变为List容器,但是不可增删其中的元素
16.7.1 复制数组
java标准类库中提供了* static方法System.arraycopy(),用它复制数组比for循环要快得多,当数据量大时使用效率明显。*
package com.array1;
import java.util.Arrays;
public class ArrayCopy {
public static void main(String[] args) {
int[] arr = new int[2000000];
Arrays.fill(arr, 5);
int[] arrCopy = new int[2000000];
long startTimeOne = System.currentTimeMillis();
for (int i = 0; i < arr.length; i++) {
arrCopy[i] = arr[i];
}
long endTimeOne = System.currentTimeMillis();
System.out.println("for循环 复制消耗时间: " + (endTimeOne - startTimeOne));
Arrays.fill(arrCopy, 0);
long startTimeTwo = System.currentTimeMillis();
System.arraycopy(arr, 0, arrCopy, 0, arr.length);
long endTimeTwo = System.currentTimeMillis();
System.out.println("System.arraycopy 复制消耗时间: " + (endTimeTwo - startTimeTwo));
}
}
output :
/usr/lib/jvm/java-8-oracle/bin/java -javaagent:/snap/intellij-idea-ultimate/54/lib/idea_rt.jar=37323:/snap/intellij-idea-ultimate/54/bin -
for循环 复制消耗时间: 9
System.arraycopy 复制消耗时间: 2
Process finished with exit code 0
16.7.2 数组的比较
Arrays提供了equals() 方法来比较数组,数组相等的条件是:元素个数相等并且对应位置的元素也相等。
16.8 总结
总是优先使用容器,除非你已证明性能成为瓶颈, 并且从容器切换到数组性能会有所提高。