参考 深入Java、数组
内存中的数组
数组引用变量只是一个引用,这个引用可以指向任何有效的内存,只有它指向有效内存时才可通过该数组变量来访问数组元素。
实际的数组对象被存储在堆(heap)内存中;若引用该数组对象的数组引用变量是一个局部变量,则它被存储在栈(stack)内存中。如图1
为什么有栈内存和堆内存?
当一个方法执行时,每个方法都会建立自己的内存栈,在该方法中定义的变量将会逐个放入这块栈内存中,随着方法的执行结束,里面的内存栈也将自然销毁。故所有方法中定义的**局部变量**都是放在栈内存里的。
在程序创建一个对象时,这个对象将被保存到运行时数据区中,以便反复利用(因为创建对象的成本通常较大),这个数据区就是堆内存。堆中对象不会随方法执行结束而销毁,即使方法结束后,这个对象还能被另一个引用变量所引用(如方法参数传递时)。只有当一个对象没有任何引用变量引用它时,系统的垃圾回收器才会在合适的时候回收它。
只要类型相互兼容,就可以让一个数组变量指向另一个实际的数组,但是,数组的长度依然不会变!
/* ArrayRam.java */
public class ArrayRam {
static public void main(String[] args) {
int[] a = {
6, 7, 8};
var b = new int[4];
System.out.println("The length of b: " + b.length);
// 让b引用指向a引用所指向的数组
b = a;
System.out.println("The length of b: " + b.length);
}
}
执行结果:
看起来长度变了啊???这是一个假象,记得:定义并初始化一个数组后,在内存中分配了两个空间,一个用于存放数组的引用变量,另一个用于存放数组本身。上图
a变量和b变量都引用了第一个数组,此时第二个数组失去了引用,变成垃圾,只有等待垃圾回收器来回收它。
操作数组的工具类:Arrays
API中的说明:
public class Arrays
extends Object
This class contains various methods for manipulating arrays (such as sorting and searching). This class also contains a static factory that allows arrays to be viewed as lists.
int binarySearch(byte[] a, byte key)
使用二分法查询key元素所在数组a里出现的索引;若不存在,返回负数。数组a必须已经按升序排序。
int[] a = {
2, 3, 4, 5};
System.out.println("The index of key=4 is " + Arrays.binarySearch(a, 4));
// The index of key=4 is 2
int binarySearch(byte[] a, int fromIndex, int toIndex, byte key)
与前一个方法类似,但只搜索数组a中fromIndex到toIndex索引的元素。
int[] a = {
2, 3, 4, 5};
System.out.println("The index of key=3 from fromIndex=0 to tofromIndex=2 is " +
Arrays.binarySearch(a, 0, 2, 3));
// The index of key=3 from fromIndex=0 to tofromIndex=2 is 1
String toString(type[] a)
将一个数组转换成一个字符串。
int[] original = {
1, 2, 9, 8, 5};
System.out.println("The elems of original: " + Arrays.toString(original));
//The elems of original: [1, 2, 9, 8, 5]
type[] copyOf(type[] original, int newLength)
把original数组复制成一个新数组,newlength是新数组的长度。
int[] original = {
1, 2, 9, 8, 5};
int[] newArray = Arrays.copyOf(original, 3);
int[] newArray2 = Arrays.copyOf(original, 8);
System.out.println("The len of original is " + original.length);
System.out.println("The elems of original: " + Arrays.toString(original));
System.out.println("The len of newArray is " + newArray.length);
System.out.println("The elems of original: " + Arrays.toString(newArray));
System.out.println("The len of newArray2 is " + newArray2.length);
System.out.println("The elems of original: " + Arrays.toString(newArray2));
/* results:
The len of original is 5
The elems of original: [1, 2, 9, 8, 5]
The len of newArray is 3
The elems of original: [1, 2, 9]
The len of newArray2 is 8
The elems of original: [1, 2, 9, 8, 5, 0, 0, 0]
*/
可以看到,如果新数组的长度比原数组的长度小,新数组就是原数组前newLength个元素;反之,新数组是原数组的所有元素,后面补充0 or false、or null
type[] copyOfRange(type[] o, int from, int to)
boolean equals(type[] a, type[] a2)
若数组a和a2长度且数组元素一一相同,则返回true。
int[] a = {
2, 3, 4, 5};
int[] b = {
2, 3, 4, 5};
int[] c = {
1, 2, 3, 4};
System.out.println("a=b: " + Arrays.equals(a, b));
System.out.println("c=b: " + Arrays.equals(c, b));
// a=b: true
// c=b: false
void sort(type[] a)
把数组a排序
int[] a = {
12, 3, 41, 5};
Arrays.sort(a);
System.out.println("sorted: " + Arrays.toString(a));
// sorted: [3, 5, 12, 41]
小结
学习了数组的知识以及操作数组的工具类的一些静态方法。
Reference: 李刚《疯狂Java讲义第五版》