数组是一种效率最高的存储和随机访问对象引用序列的方式,数组有固定的尺寸,是同一数据类型的集合。
数组相比其他容器具有效率、类型和保存基本类型的优势,缺点是数组只是个存储机制,没有丰富的方法可用,也没有自动扩容的机制。
1.1. 基本类型与性能优势
数组可以持有基本类型,而容器则不能,容器看起来能够持有基本数据类型,其实是通过自动装箱拆箱机制,把基本类型转为对应的包装类型对象。自动装箱拆箱是需要开销的,而且对象占用的内存更多。
1.2. Java数组协变类型导致运行时异常
Java数组是可以协变类型的,即一个 String 数组也是一个 Object 数组。但不恰当的数组协变可能导致异常。
String[] strings = new String[10];
strings[0] = "123" ;
Object[] objects = strings;
objects[1] = Integer. valueOf (10);
这几行代码在编译时没错,但在运行时会抛出这样的异常:
Exception in thread "main" java.lang.ArrayStoreException : java.lang.Integer
使用列表则可以避免这种错误,
List< Object > list = new LinkedList<String>() ;
这行代码就不能编译通过,因为列表的类型不是协变的。
优先使用 链表lists 而不是数组 arrays 。
1.3. 数组拷贝
数组拷贝不应该自己编写循环来完成,应该使用System. arraycopy 方法来完成,除了代码更简洁外,还能带来性能的提升,因为这是个本地方法,而且针对每种基本类型进行重写,性能是最优的。
还可以使用java.util.Arrays 的 copy* 方法,这些方法不需要提供目标数组,在方法内新建数组,调用 System. arraycopy 进行数据拷贝,然后返回新数组, 简化了用户调用。
1.4. Arrays工具类
Arrays工具类提供了数组的:搜索、拷贝、部分拷贝、比较、 hashcode 计算、填充、排序、转换为字符串 的功能,对数组进行操作,应优先考虑这些方法。
public class LearnArrays { public static void main(String[] args) { int[] iarr = new int[] { 3, 2, 4, 5, 8, 7, 6, 1, 9, 0 }; int index = Arrays.binarySearch(iarr, 8); // 搜索 System.out.println("index of 8 is :" + index); int[] copy = Arrays.copyOf(iarr, 4); // 拷贝 String copyString = Arrays.toString(copy); // 把数组内容表示为String System.out.println(copyString); Arrays.sort(iarr); // 排序 System.out.println("after sort :" + Arrays.toString(iarr)); int code = Arrays.hashCode(iarr); // 计算hashcode System.out.println("hash code :" + code); } }
1.5. 总结
A、 优先使用 链表lists ,而不是数组 arrays 。
B、 如果非要持有基本数据类型的容器,可以使用Apache Commons Primitives 库。