1 数组
1.1 性能
- printList打印表:线性时间 O(N);
- find(x)返回指定位置上的元素:常数时间 O(1);
- 插入和删除:最坏情况O(N), 最好情况O(1), 平均为线性时间;
所以数组一般通过在高端进行插入操作建成,之后只访问,不进行插入和删除,尤其是在表的前端。
1.2 栈内存与堆内存
新建的数组中保存的实际对象是保存在堆(heap)中的;如果引用该数组的数组引用变量是一个局部变量,那么它被保存在栈(stack)中。例如:
int[] test = new int[100];
test这个引用变量是保存在栈中的,那新建的100int的数据是保存在堆中的。虽然它还没有初始化,但是内存已经分配给它了。
当一个方法执行时,每个方法都会建立自己的内存栈,在这个方法内定义的局部变量都会放入这块内存里,随着方法的执行结束,这个方法的内存栈也将自然销毁。因此,所有在方法中定义的局部变量都是放在栈中的。
但是,程序中被new出来的东西一般都放在堆内存中以便程序反复利用,这个堆内存也叫作【运行时数据区】,这个称号更能表述它的性质不是吗。
堆中的对象是不会随方法的结束而立刻销毁,只要还有引用变量指向它,GC就不会回收。这一点在方法的参数传递中很常见。只有当堆中的对象没有一个引用变量指向它,GC才会在合适的时候回收它。所以在JDK源码中,我们经常看到一些没用了的引用变量被显式地赋值为null,就是为了让GC尽快回收被创建的对象。
Java 数组初始化的两种方法:
- 静态初始化: 程序员在初始化数组时为数组每个元素赋值;
- 动态初始化: 数组初始化时,程序员只指定数组的长度,由系统为每个元素赋初值。
public class ArrayInit {
public static void main(String[] args) {
//静态初始化数组:方法一
String cats[] = new String[] {
"Tom","Sam","Mimi"
};
//静态初始化数组:方法二
String dogs[] = {
"Jimmy","Gougou","Doggy"};
//动态初始化数据
String books[] = new String[2];
books[0] = "Thinking in Java";
books[1] = "Effective Java";
System.out.println(cats.length);
System.out.println(dogs.length);
System.out.println(books.length);
}
}
典型错误是:
int[] nums = new int[6]{
1,2,3,4,5,6};
1.3 多维数组
常规的说法是“Java支持多维数组”,但是,从本质上来讲,根本没用什么多维数组,不过是引用变量数组而已。当然,说法上不用太纠结,你开心就好^_^
这里就强调一下多维数组的新建,两种:
//先新建第一纬度,再新建第二纬度
int[][] test = new int[4][];
for(int i=0; i<test.length;i++){
test[i] = new int[100];
}
//两个维度同时新建
int[][] test2 = new int[4][100];
System.out.println(test2.length);
System.out.println(test2[0].length);