相信大家對C/C++中的數組相關操作比較熟悉,而它在Java中的使用有些不一樣的地方。
主要有:
1)聲明是用elementType [ ] array;的形式(當然C/C++中的聲明方式如elementType array[ ]也行,但在Java中不推薦),其中array叫做引用變量。與C/C++不同的是聲明一個數組並不分配內存空間,只有創建的時候才分配;
2)創建:elementType [ ] array = new elementType [size];這樣纔會分配內存空間;
3)數組作爲參數傳遞時,傳遞的是引用(java中沒有指針,但是我感覺引用和指針從對內存中變量值的改變來講有一丁點形似),所以被調方法體中對變量的改變也會改變調用者參數的值,這一點和C/C++有很大區別的!
4)針對Java的數組,還有個專門的for-each循環,這個用起來也是很方便的。
5)數組的複製方式不同,內存的變化是不一樣的,如數組list2 = list1的操作,將list1的引用賦值給了list2,而list2原來的引用就會被Java虛擬機當成垃圾自動清除;還有方法調用中作爲參數傳遞;System類中的arraycopy;
對於以上幾點的不同,給出一個簡單的程序幫助理解,請童鞋們跑跑程序自己體會。源代碼如下所示:
package Arrays;
public class arraysPractice {
//數組值傳遞的幾種方式,注意其中內存值的變化
public static void main(String [] args){
int[] list1 = new int[10];
int[] list2 = new int[10];
for(int i = 0;i < 10;i++){
list1[i] = i;
list2[i] = i+1;
}
System.out.println("list1 is ");
for(int u:list1)//for-each循環
System.out.print(u+" ");
System.out.println("\nlist2 is ");
for(int u:list2)
System.out.print(u+" ");
System.out.println();
System.out.println("list2 to list1,and list2 is ");
list2 = list1;//將list1的引用值複製給了list2,list2原來引用的數組不能繼續引用
for(int u:list2)
System.out.print(u+" ");
System.out.println();
System.out.println("arraycoppy list2 to list1 ");
System.arraycopy(list2, 0, list1, 0, list1.length);//System類方法傳遞數組
//list1和list2具有相同的內容,但有獨立的內存空間
for(int u:list2)
System.out.print(u+" ");
//給方法傳遞的是這個引用,參數傳遞的共享信息,即方法中的數組和傳遞的數組是一樣的,值會以期改變
printArray(new int[]{3,1,2,6,4,2});//給方法傳遞數組,匿名數組
int x = 1;
int[] y = new int[10];
m(x,y);
System.out.println("\nx is "+x);
System.out.println("y[0] is +"+y[0]);
int[] a = {1,2};
System.out.println("Befor invoking swap");
System.out.println("array is {"+a[0]+","+a[1]+"}");
swap(a[0],a[1]);
System.out.println("After invoking swap");
System.out.println("array is {"+a[0]+","+a[1]+"}");
System.out.println("Befor invoking swapFirstTwoInArray");
System.out.println("array is {"+a[0]+","+a[1]+"}");
swapFirstTwoInArray(a);
System.out.println("After invoking swapFirstTwoInArray");
System.out.println("array is {"+a[0]+","+a[1]+"}");
}
public static void swap(int n1,int n2){
int temp = n1;
n1 = n2;
n2 = temp;
}
public static void swapFirstTwoInArray(int[] array){
int temp = array[0];
array[0] = array[1];
array[1] = temp;
}
public static void m(int number,int[] numbers){
number = 1001;
numbers[0] = 5555;
}
public static void printArray(int[] array){
System.out.println("\nprintArray is ");
for(int i = 0;i < array.length;i++)
System.out.print(array[i]+" ");
}
}
運行結果如右圖所示:理解了上述數組的基本概念之後,就可以進行諸如排序,查找方法的設計了,之前介紹過用方法的思想進行編程,所以接下來的設計都基於用方法來實現,這樣main方法可以用方法的“集合”來編寫,看起來方便,便於理解,而且代碼重用性也很高。對後續的開發而言更加方便。
示例一:數組建立、查找、亂序、排序(線性和二分)集錦(爲了熟悉數組,一定自己先進行設計)。代碼如下所示:
package Blog;
import java.util.Scanner;
public class blogTryProject {
//數組建立、查找、亂序、排序集錦
public static void main(String [] args){ //main方法
int[] check = creatChars(10);
printTheNumberForLinearFind(linearFind(check, 11),11);//線性查找及其打印
printTheNumberForLinearFind(linearFind(check, 3),3);
printTheNumberForMidFind(midFind(check,16), 16);//二分查找及其打印
printTheNumberForMidFind(midFind(check,2), 2);
upSet(check);//隨機亂序目標數組
check = chooseSort(check);//選擇排序
printArray(check);//打印數組
upSet(check);
check = insertSort(check);
printArray(check);
}
//插入法排序
public static int[] insertSort(int[] chars){
System.out.println("\ninsertSort");
for(int i = 1;i < chars.length;i++){
for(int j = 0;j < i;j++){
if(chars[i] < chars[j]){
int temp = chars[i];
chars[i] = chars[j];
chars[j] = temp;
}
}
}
return chars;
}
//選擇法排序
public static int[] chooseSort(int[] chars){
System.out.println("\nchooseSort");
for(int i = 0;i <chars.length;i++){
int currentMin = chars[i];
int currentMinIndex = i;
for(int j = i + 1;j < chars.length;j++){
if(currentMin > chars[j]){
currentMin = chars[j];
currentMinIndex = j;
}
}
if(currentMinIndex != i){
chars[currentMinIndex] = chars[i];
chars[i] = currentMin;
}
}
return chars;
}
//亂序
public static void upSet(int[] chars) {
System.out.print("\n隨意打亂前的數組爲:");
for(int u:chars){
System.out.print(u+" ");
}
for(int i = 0;i < chars.length;i++){
int index = (int)(Math.random()*chars.length);
int temp = chars[i];
chars[i] = chars[index];
chars[index] = temp;
}
System.out.print("\n隨意打亂後的數組爲:");
for(int u:chars){
System.out.print(u+" ");
}
}
//打印二分法查找的數組元素位置
public static void printTheNumberForMidFind(int i,int key){
if(i >= 0)
System.out.println(key+"是數組的元素!");
else
System.out.println(key+"不是數組的元素!");
}
//打印線性法查找的數組元素位置
public static void printTheNumberForLinearFind(int i,int key){
if(i == -1)
System.out.println(key+"不是數組的元素!");
else
System.out.println(key+"是數組的第"+(i+1)+"個元素!");
}
//二分查找
public static int midFind(int[] check,int key){
int low = 0;
int high = check.length - 1;
int mid = (low + high) / 2;
while(low <= high){
if(check[mid] == key)
return mid;
else if(check[mid] > key){
high = mid - 1;
mid = (low + high) / 2;
}
else{
low = mid + 1;
mid = (low + high) / 2;
}
}
return -low - 1;
}
//線性查找
public static int linearFind(int[] check,int key){
for(int i = 0;i < check.length;i++){
if(key == check[i])
return i;
}
return -1;
}
//創建數組
public static int[] creatChars(int number){
int[] chars = new int[number];
for(int i = 0;i < chars.length;i++)
chars[i] = i+1;
return chars;
}
//打印數組
public static void printArray(int[] chars){
for(int u:chars)
System.out.print(u+" ");
}
}
運行效果如右圖所示:通過上面的學習,作者發現用方法去打印不同的數據類型的數組時需要重新編寫方法,用起來很不方便,所以有必要介紹方法的重載,以滿足同一功能不同數據類型的需求。重載就是方法有同樣的名稱(爲了方便程序的閱讀識別與編程通常其功能也相同),但是參數列表不相同的情形,這樣的同名不同參數的方法之間,互相稱之爲重載方法。
重載關心的是參數:有參無參,參數類型不同,參數數量不同,不同類型的參數順序不同,都可以實現方法的重載。而返回值類型的不同、修飾符的不同對重載是沒有印象的。
Java中的重載和C/C++中的重載也是有所區別的,後者是“一勞永逸“,前者到目前我的理解是要將不同數據類型的操作複製集成在一個類中的,在調用時先聲明一個類,再以調用類中方法的形式使用。下面請看示例程序。
示例二:方法的重載舉例。源代碼如下所示:
package Arrays;
import java.util.Scanner;
import java.util.Arrays;
public class array {
//一維數組排序、查找及相關方法的重載
public static void main(String [] args){
printSort PS = new printSort();//打印類的函數重載
printFind PF = new printFind();
midFind FM = new midFind();//查找類的函數重載
double[] numbers = {6.0,4.4,1.9,2.9,3.4,3.5};
PS.beforAndAfterSortPrint(numbers);
char[] chars = {'a','A','4','F','D','P'};
PS.beforAndAfterSortPrint(chars);
FM.binarySearch(numbers, 3.4);
FM.binarySearch(chars, 'A');
//Arrays類集成了很多對數組操作的方法,用起來很方便,它包含在java.lang包中,屬於預定義類
Arrays.fill(numbers, 3.3);
PF.print(numbers);
Arrays.fill(chars, 0,3,'G');
PF.print(chars);
}
}
class printFind{ //查找打印類,即打印方法的重載
void print(double[]chars){
System.out.println();
for(double u:chars)
System.out.print(u+" ");
System.out.println();
}
void print(char[]chars){
System.out.println();
for(char u:chars)
System.out.print(u+" ");
System.out.println();
}
}
class midFind{ //顯示二分查找結果的類
void binarySearch(double[] chars,double num){
System.out.println("\nnumbers(10)的二分查找結果爲"
+Arrays.binarySearch(chars, num));
}
void binarySearch(int[] chars,int num){
System.out.println("\nnumbers(10)的二分查找結果爲"
+Arrays.binarySearch(chars, num));
}
void binarySearch(char[] chars,char num){
System.out.println("\nnumbers(10)的二分查找結果爲"
+Arrays.binarySearch(chars, num));
}
}
class printSort{ //打印排序前後數組元素的類
void beforAndAfterSortPrint(double[] numbers){
overLoad ol = new overLoad();//方法的重載
System.out.println("\nBefore sort");
ol.printArray(numbers);
Arrays.sort(numbers);
System.out.println("\nAfter sort");
ol.printArray(numbers);
}
void beforAndAfterSortPrint(int[] numbers){
overLoad ol = new overLoad();//方法的重載
System.out.println("\nBefore sort");
ol.printArray(numbers);
Arrays.sort(numbers);
System.out.println("\nAfter sort");
ol.printArray(numbers);
}
void beforAndAfterSortPrint(char[] numbers){
overLoad ol = new overLoad();//方法的重載
System.out.println("\nBefore sort");
ol.printArray(numbers);
Arrays.sort(numbers);
System.out.println("\nAfter sort");
ol.printArray(numbers);
}
}
class overLoad{ //直接打印的類
void printArray(double[] chars){
for(double u:chars)
System.out.print(u+" ");
}
void printArray(int[] chars){
for(double u:chars)
System.out.print(u+" ");
}
void printArray(char[] chars){
for(char u:chars)
System.out.print(u+" ");
}
}
運行結果如右圖所示:
可以看到上述main方法的編寫十分簡潔明瞭,並且後續編程需要相關方法操作時直接調用即可,無需重新編寫代碼,開發效率成倍提高!