1, 数组的定义:
type[] arrayName;
type arrayName[];
注:推荐使用type[] arrayname;这种定义格式,因为这种方式不仅具有更好的语义,也具有更好的可读性,
对于type[] arrayName;很容易理解这是定义一个变量,其中变量的类型是type[]。
2, 数组的初始化:
Java语言中数组必须先初始化,然后才可以使用,所谓初始化,就是为数组的元素分配内存空间,并为每个数组元素赋初始值。
2.1静态初始化:初始时由程序员显式地指定每个元素的初始值,由系统决定数组的长度
格式:arrayName=newtype[]{element1,element2,element3…};
简化:arrayName={element1,element2,element3…};
2.2动态初始化:初始化时程序员只指定数组的长度,由系统为数组元素分配初始值
格式:arrayName=newtype[length];
3,数组在内存中的表现形式:
数组引用变量只是一个引用,这个引用可以指向任何有效的内存,只有该引用指向有效内存后,才可以通过该数组变量来访问数组,实际的数组元素被存储在堆(heap)内存中,数组引用变量是一个引用,被存储在栈(Stack)内存中,数组在内存中的存储示意图如下:
注:栈内存和堆内存
当一个方法执行时,每个方法都会建立自己的一个内存栈,在这个方法内定义的变量将会逐个放入到这块栈内存里,随着方法的执行结束,这个方法的内存栈也会自然销毁了。因此,所有在方法中定义的变量都是放在栈内存中的,当我们在程序中创建一个对象时,这个对象将会保存到运行时数据区中,以便反复利用(因为对象的创建成本较大),这个运行时数据区就是堆内存。堆内存中的对象不会随着方法的结束而销毁,即使方法结束后,这个对象还可以被另外一个引用变量所引用(方法的参数传递时很常见),则这个对象依然不会被销毁。只有当一个对象没有任何一个引用变量引用它时,系统的垃圾回收机制会在合适的时候回收它。
4, 多维数组
4.1Java中并没有真正的多维数组,只有数组的数组,Java中多维数组不一定是规则矩阵形式
Java语言里的数组类型是引用类型,因此,数组变量其实是一个引用,这个引用指向真实的数组内存,数组元素的类型也可以是引用,如果数组元素的引用再次指向真实的数组内存,这种情形看上去很像多维数组。
4.2定义一个多维数组
int[][] xx;
xx=new int[3][];
xx[0]=new int[3];
xx[1]=new int[2];
4.3多维数组在内存中的表现形式,如图5, 关于数组常见算法的代码剖析:
5.1拆分查找:
class HalfSearch
{
/*
在一个有序的数组中查找一个元素的位置;
例如:有数组{0,2,4,6,8,10,12}查找10的位置index=5
*/
public static void main(String[] args)
{
int[] arr=new int[]{0,2,4,6,8,10,12};
int index=getIndex(arr,12);
System.out.println("index="+index);
}
//一般性做法,效率较低的算法
/*
public static int getIndex(int[] arr,int key)
{
for(int i=0;i<arr.length;i++)
{
if(arr[i]==key)
return i;
}
return -1;
}
*/
//折半查找法
/*
public static int getIndex(int[] arr,int key)
{
int min=0;
int max=arr.length-1;
int mid=(min+max)/2;
while(arr[mid]!=key)
{
if(key>arr[mid])
min=mid+1;
else
max=mid-1;
if(min>max) //判断查找不到的情况,返回-1
return -1;
mid=(min+max)/2; //折半
}
return mid;
}
*/
//折半查找法的第二种方式:效率稍高
public static int getIndex(int[] arr,int key)
{
int min=0;
int max=arr.length-1;
int mid;
while(min<=max)
{
mid=(min+max)/2;
if(key>arr[mid])
min=mid+1;
else if(key<arr[mid])
max=mid-1;
else
return mid;
}
return -1;
}
}
5.2选择排序:
class SelectSort
{
public static void main(String[] args)
{
int[] arr=new int[]{2,1,5,3,6,4,8,9,7};
System.out.println("原数组:");
Print(arr);
System.out.println();
System.out.println("排序后:");
SelectSort(arr);
}
//选择排序,对一个数组进行升序排列
//打印原数组
public static void Print(int[] arr)
{
System.out.print("[ ");
for(int i=0;i<arr.length;i++)
{
if(i!=arr.length-1)
System.out.print(arr[i]+", ");
else
System.out.print(arr[i]+"]");
}
}
//选择排序
public static void SelectSort(int[] arr)
{
for(int i=0;i<arr.length-1;i++)
{
for(int j=i+1;j<arr.length;j++)
{
if(arr[i]>arr[j])
{
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
}
Print(arr);
}
}
5.3冒泡排序:
class BubbleSort
{
public static void main(String[] args)
{
int[] arr=new int[]{2,1,5,3,6,4,8,9,7};
System.out.println("原数组:");
Print(arr);
System.out.println();
System.out.println("排序后:");
BubbleSort(arr);
}
//打印原数组
public static void Print(int[] arr)
{
System.out.print("[ ");
for(int i=0;i<arr.length;i++)
{
if(i!=arr.length-1)
System.out.print(arr[i]+", ");
else
System.out.print(arr[i]+"]");
}
}
//冒泡排序
public static void BubbleSort(int[] arr)
{
for(int i=0;i<arr.length;i++) //for(int i=arr.length-1;i>0;i--)
{
for(int j=0;j<arr.length-i-1;j++) //for(int j=0;j<x;j++)
{
if(arr[j]>arr[j+1])
{
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
Print(arr);
}
}
6.操作数组的工具类<Arrays>
Java.util包中封装了很多关于java数组的工具方法,这些方法都是静态的。
详情参见JDK 1.6API文档,有更好的解释。
总结:关于数组这一节的知识并不多,主要要学会数组的定义,理解好数组在内存中的表现形式,这对日后开发有很好的帮助。除此之外,还要掌握以上常见的排序算法,尤其是冒泡排序,虽然在开发中不常见,但是在面试时出现的概率很大。
此外,通过查阅API文档,发现了操作数组工具类Arrays有很多方法,在这里做了一些常见方法的总结,这些方法都是静态的,相当实用,例如sort方法,最好牢记下来,以便开发时直接拿来用,不必翻阅API文档。
2013.03.15