复制数组
Java在System类中提供了一个特殊的方法arraycopy(),用于实现数组之间的复制操作。
本示例将演示数组的复制功能,操作步骤如下。
(1)创建CopyArray类,在main()方法中输入以下程序关键代码。
src/com/wsy/CopyArray.java关键代码:
int i;
int arr1[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; //源数组
int arr2[] = new int[10]; //复制数组
System.arraycopy(arr1, 0, arr2, 0, arr1.length); //将arr1数组复制到arr2数组
for (i = 0; i < arr2.length; i++)
System.out.print(arr2[i] + ","); //打印arr2数组
System.out.println();
代码说明如下。
其实数组在Java中可以看作一个对象,数组的引用和数组的实例也是分开的,所以如果希望复制整个数组的数据时,就不能简单地使用指定语句,因为这样访问的还是同一个数组。不过虽然数组有点像对象,但是数组毕竟不是继承自java.lang.Object类的对象,所以就没有clone()这个用来复制对象实例的方法。
可以自己利用循环来做数组的复制,例如有arrayA、arrayB两个数组,现在要将arrayA数组中的数据复制到arrayB数组中:
for (i=0;i<arrayA.length;i++)
arrayB[i]=arrayA[i];
其实也不难,一个for循环语句就可以了。不过Java中也提供了一个方法来复制一个数组,就是“System.arraycopy”方法。例如:
语法:
System.arraycopy (arrayA,0,arrayB,0,a.length);
arrayA:来源数组名称。
0:来源数组起始位置。
arrayB:目的数组名称。
0:目的数组起始位置。
arrayA.length:复制来源数组元素的个数。
使用arraycopy这个方法时,需要上述5个参数,依序是来源数组、来源数组数据起始位置、目的数组、目的数组数据起始位置、复制数组个数。由这些参数可知这个方法在使用上非常有弹性。
如果只想把arrayA数组中的第1、2、3位置的数据拷贝到arrayB数组中的第2、3、4的位置上,那么可以改写如下:
语法:
System.arraycopy(arrayA,1,arrayB,2,3);
arrayA:来源数组名称。
1:来源数组起始位置为第二个元素。
arrayB:目的数组名称。
2:目的数组起始位置为第3个元素。
3:在来源数组第二个元素开始复制3个元素。
如果需要将来源数组和目的数组都指定为同一个数组,或是说引用到同一个数组时,Java会复制一份临时数组,然后根据参数的要求,再从刚才产生的临时数组拷贝回来,所以不会造成读和写的冲突。
使用循环对数组做复制操作与使用System.arraycopy方法对数组做复制操作最大的差别在于System.arraycopy这个方法速度上会比较快。
排序数组
在Java中为数组中的元素排序需要使用sort()这个方法。该方法是java.util类库中的Arrays类。
Arrays类中有一系列方法,提供了操作数组的实用功能,其中包括的方法有:equals()、fill()、binarySearch()、asList(),equals()比较两个数组是否相等,fill()向数组填充整个数组,binarySearch()在排好序的数组中查找元素,asList()的参数是任何类型的数组,将数组转化为List容器。
Arrays类可以协助Java用户操作数组,它提供了几个方法:
sort()
快速排序
binarySearch()
对已经排序好的数组进行二叉搜索,如果找到结果返回该元素的索引值,否则返回负值
fill()
填充数组
equals()
比较数组中的元素值是否相等,如果是返回true,否则返回false
主要使用Arrays类中的sort()方法,该方法的参数为任意基本类型的数组,也可以对任意对象数组进行排序。
数组排序在操作数组中应用广泛,使用Arrays类调用,例如:
语法:
Arrays.sort(a);
a:排序数组名称。
import java.util.Arrays;
public class SortArray {
public static void main(String[] args) {
String []s=new String[]{"abc","ABC","EDF","234"};
Arrays.sort(s);
System.out.println(Arrays.asList(s));
}
}
代码说明如下。
上述代码中定义了一个字符型数组,其中包括4个元素,包括大写字母、小写字母、数字,若想对这个数组进行排序,使用的是先前提到的sort()方法,参数为数组s,排序后打印数组s,此时可以使用for循环语句对数组进行打印,但Arrays类库为用户提供了更为方便的打印形式,使用asList()方法,参数为需要打印的数组名称。
Java中的String排序算法是根据字典编排顺序排序的,所以数字排在字母前面,大写字母排在小写字母前面。如果想忽略大小写字母将单词放在一起排序,可以修改上述代码。
下面是一个忽略字符串大小写排序的例子,操作步骤如下。
(1)创建SortArray2类,在main()方法中输入以下程序关键代码。
src/com/wsy/SortArray2.java关键代码:
String[] sa=new String[]{"b","C","a","234"};
Arrays.sort(sa, new SingleCompare()); //忽略大小写给数组sa排序
System.out.println(Arrays.asList(sa)); //打印数组sa
(2)在SortArray2类中创建类SingleCompare,关键代码如下:
src/com/wsy/SortArray2.java关键代码:
public class SingleCompare implements Comparator{
public int compare(Object o1,Object o2){ //重写compare方法
String s1=(String)o1;
String s2=(String)o2;
return s1.toLowerCase().compareTo(s2.toLowerCase());
//将字符串s1、s2大写转化为小写后行比较
}
}
代码说明如下。
在上述代码中实现了Comparator接口,该接口强行对某些对象进行整体排序,可以将Comparator传递给sort()方法,从而允许在排序上实现精确控制。Comparator有两个方法,分别为compare()方法和equals()方法,可以重写compare()方法实现自己需要的比较,例如上述代码中比较两个字符串的大小写情况,在这里使用了String类中的toLowerCase()方法,此方法将字符串中的大写字母转换为小写字母,将字符串从大写字母转换为小写字母后再进行比较,然后将比较结果传递给sort()方法进行排序。
compare()方法返回负数、零、或正整数,分别对应于第一个参数小于、等于或大于第二个参数。
比较数组
Arrays类提供了equals()方法,用来比较整个数组,数组相等的条件是数组元素的个数必须相等,并且对应的位置元素也相等,这时候可以通过对每个元素使用equals()方法作比较来判断。例如:
语法:
Arrays.equals(arrayA,arrayB);
arrayA:待比较数组名称。
arrayB:待比较数组名称。
(1)创建ComparingArrays类,在main()方法中输入以下程序关键代码。
src/com/wsy/ComparingArrays.java关键代码:
int[]a1={1,2,3,4,5,6,7,8,9,0};
int[]a2=new int[9];
System.out.println(Arrays.equals(a1, a2)); //打印数组a1与a2的比较结果
int[]a3={1,2,3,4,5,6,7,8,9,0};
System.out.println(Arrays.equals(a1, a3)); //打印数组a1与a3的比较结果
int[]a4={1,2,3,4,5,6,7,8,9,5};
System.out.println(Arrays.equals(a1, a4)); //打印数组a1与a4的比较结果
上述代码中定义了3个数组,第一个数组直接给出数组的值,声明和初始化放在一起,从笔者给出的数值可以看出数组a1的长度为10,而定义的第二个数组的长度为9,所以使用Arrays.equals()方法进行比较后结果为false。再次定义一个与a1相同的数组a3,比较后结果为true,这时笔者再次定义一个数组a4,数组a4与数组a1元素个数相同,元素内容不同,比较数组a1与a4结果为false。
搜索数组
搜索数组中的元素需要使用binarySearch()这个方法,此方法也为Arrays的一系列方法之一。
在使用binarySearch()方法之前有一点要非常值得注意,就是被查找的数组必须是已经排序好的,因为此时是二叉树查找,这个二叉树必须是排序过的,这样查找出来的结果才会有意义。如果找到了需要查询的结果,binarySearch()方法返回值为需要查找的内容在数组中的位置,如果没有查找到要找的数据,那么返回一个“负数”,至于这个负数的值会是多少,就看这棵二叉树下一个插入位置的索引值是多少了。
Arrays类引用binarySearch方法,例如:
语法:
int i=binarySearch(a,"abc");
a:搜索数组的名称。
abc:需要在数组中查找的内容。
int[] a={1,2,3,4,1,2,3};
Arrays.sort(a); //将数组a排序
Arrays.binarySearch(a, 4); //查找数值4在数组a中的位置
System.out.print("排序后的数组为:");
for(int i=0;i<a.length;i++){
System.out.print(+a[i]+" "); //打印排序后的数组a
}
System.out.println();
int location=Arrays.binarySearch(a, 4);
System.out.println("查找4的位置是"+location+",a["+location+"]="+a[location]);
//打印数值4在数组a中的位置以及对应的元值
}
代码说明如下。
上述代码中首先定义了一个int型数组,然后笔者使用了sort()方法对此数组进行排序,因为只有排序后才能进行查找工作,为了使4在数组中位置更加清晰,笔者将排序后的数组打印,然后进行查找,返回一个int型变量即为4在数组中的位置。
如果排序时使用了comparator,那么在搜索时也要使用comparator。
(1)创建SearchArray2类,在main()方法中输入以下程序关键代码。
src/com/wsy/SearchArray2.java关键代码:
String[] a={"1","2","3","4","1","2","3"};
Arrays.sort(a, new SingleCompareNew ()); //忽略数组中大小写后对数组进行排序
System.out.print("排序后的数组为:");
for(int i=0;i<a.length;i++){
System.out.print(a[i]+" "); //打印数组
}
System.out.println();
int location=Arrays.binarySearch(a, "4", new SingleCompareNew ());
System.out.println("查找4的位置是"+location +",a["+location+"]="+a[location]);
(2)在SearchArray2类中定义一个类SingleCompareNew,程序代码如下:
src/com/wsy/SearchArray2.java关键代码:
class SingleCompareNew implements Comparator{
public int compare(Object o1,Object o2){ //重写compare()方法
String s1=(String)o1;
String s2=(String)o2;
return s1.toLowerCase().compareTo(s2.toLowerCase());
}
}
定义一个类SingleCompareNew,此类实现了Comparator接口,此时需要重写Comparator内的compare()方法,在排序时使用sort(数组名称,new Comp()),正因为在排序时候使用了这样的限制,所以在搜索时也需要提供同样的Comparator。
填充数组
Arrays类库中为用户提供填充数组的方法为fill()方法,虽然可以填充数组,但此方法的功能有限,只能使用同一个数值进行填充,但此方法可以在指定位置进行填充。
Arrays类引用fill()方法实现填充数组,例如:
语法:
int array[]=new int[10];
Arrays.fill(array,11);
array:将被填充数组的名称。
上述代码意在将数值11填充到数组a中。
创建FillingArrays类,在main()方法中输入以下程序关键代码。
src/com/wsy/FillingArrays.java关键代码:
int size=0;
if(args.length!=0)
size=Integer.parseInt(args[0]); //取第一个参数的值
int[]a1=new int[size];
Arrays.fill(a1, 11); //将数值11填充到数组a1中
for(int i=0;i<a1.length;i++){
System.out.print("a1["+i+"]="+a1[i]+" "); //打印数组a1
}
System.out.println();
在上述代码中定义一个int型数组,此数组的长度为size变量,此变量的值为用户在终端输入而定,Java为主函数提供了一个数组参数,此数组用来接收用户在终端上输入的值,args[0]代表用户输入的第一个值,args[1]代表用户输入的第二个值,以此类推。
传递数组
数组名称实际上就是一个引用,所以传递数组实质上就是传递引用。当方法传递引用时,只需在方法参数中指定引用的名称即可。
将数组传递给方法,应该使用不加方括号的数组名,例如:
语法:
int array[] = new int[24]; // 声明一个数组
modify(array); // modify方法调用
array:要传递的数组名称。
上述代码是在方法调用时的写法,如果是定义一个方法,参数为数组,例如:
语法:
void modifyArray(int b[]){}
b:参数。
这表示modifyArray()方法正准备接收一个整型数组,名称为b。
int array[]={1,2,3,4,5};
for(int i=0;i<array.length;i++){
System.out.println("没有传值之前的数组为:"+array[i]); //打印没有调用modifyArray()方法的数组值
}
modifyArray(array); //调用方法
for(int i=0;i<array.length;i++){
System.out.println("传递之后数组的数组为:"+array[i]); //打印调用modifyArray()方法后的数值
}
在PassArray类中定义一个modifyArray()方法,它的参数为数组,程序代码如下:
src/com/wsy/PassArray.java关键代码:
public static void modifyArray (int array[]){
for(int i=0;i<array.length;i++){
array[i]*=2; //将数组array中的每个
素都乘以2
}
}
代码说明如下。
l 首先创建一个方法modifyArray(),参数为int型数组,在该方法内使用for循环语句将传递过来的数组中每一个数乘以二。
l 在主函数中定义一个数组,打印没有改变之前的数组的值。
l 调用modifyArray()方法,由于modifyArray()方法为static的,所以在主函数中可以直接调用。
l 改变数组值后,打印数组。